\(\\\)

\(Description\)


给出一张\(N\times M\)的棋盘,每个格子最多放置一个棋子,一个合法的放置方案需满足:

  • 每列至多放置一个棋子
  • 对于第\(i\)行,前\(L_i\)个格子中恰好只放一个,后\(R_i\)个格子中恰好只放一个

求合法方案数对\(10^9+7\)取模后的值。

  • \(N\in [1,50]\),\(M\in [2,200]\),\(L_i,R_i\in [1,M]\),\(L_i+R_i\le M\)

\(\\\)

\(Solution\)


打死都想不到状态设计

注意到行之间无法记录以上各列状态直接转移,所以以列为状态。

考虑只有左边的限制:

  • 设计\(f[i][j]\)表示处理到前\(i\)列,还有\(j\)列未放置棋子的方案数。
  • 考虑状态向后更新,每次做到第\(i\)列,统计左区间限制的右端点为下一列的行数\(l_{i+1}\),则下一列的这些限制都必须完成,因为这些行在哪一列被满足顺序无关,所以需要乘上排列,有\(f[i+1][j+1-l_{i+1}]+=f[i][j]\times P_{\ j}^{\ l_{i+1}}\)

考虑只有右边的限制:

  • 设计\(f[i][k]\)表示处理到前\(i\)列,还有\(k\)行的限制未满足的方案数。
  • 向后更新,但是需要同时统计右区间限制的左端点为下一列的行数\(r_{i+1}\)和下一列不被右区间限制覆盖的行数\(mid_{i+1}\),考虑这一列放一个棋子放在上面那一种里,分情况讨论转移即可。

把它们合起来:

  • \(f[i][j][k]\)表示处理到第\(i\)列,前面有\(j\)列还未放置棋子,还有\(k\)行未满足的方案数。

  • 对于每一列\(i\),统计左区间限制的右端点为当前列的行数\(l_i\)、右区间限制的左端点为当前列的行数\(r_i\)、当前列不被左右区间限制覆盖的行数\(mid_i\)。

  • 同样每次到达左区间限制的右边界时,再考虑如何满足这些左区间,本列的放置考虑三种:

    • 满足一个左区间,此时需乘上一个排列数:\(\begin{align}f[i+1][j+1-l_{i+1}][k+r_{i+1}]+=f[i][j][k]\times P_{\ j+1}^{\ l_{i+1}}\end{align}\)
    • 满足一个右区间,注意需要乘上左右两侧的方案数:\(\begin{align}f[i+1][j-l_{i+1}][k+r_{i+1}-1]+=f[i][j][k]\times P_{\ j}^{\ l_{i+1}}\times (k+r_{i+1})\end{align}\)
    • 都不满足,放在一个中间区间里,乘上左侧和中间的方案数:\(\begin{align}f[i+1][j-l_{i+1}][k+r_{i+1}]+=f[i][j][k]\times P_{\ j}^{\ l_{i+1}}\times mid_{i+1}\end{align}\)
  • 边界\(f[0][0][0]=1\),答案\(\sum_{i=1}^{m}f[m][i][0]\)

\(\\\)

\(Code\)


  1. #include<cmath>
  2. #include<cstdio>
  3. #include<cctype>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<iostream>
  7. #include<algorithm>
  8. #define N 60
  9. #define M 210
  10. #define R register
  11. #define gc getchar
  12. #define mod 1000000007
  13. using namespace std;
  14. typedef long long ll;
  15. ll fac[M]={1},c[M][M]={1},ans;
  16. ll n,m,l[M],r[M],mid[M],f[M][M][N];
  17. inline ll rd(){
  18. ll x=0; char c=gc();
  19. while(!isdigit(c)) c=gc();
  20. while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}
  21. return x;
  22. }
  23. int main(){
  24. n=rd(); m=rd();
  25. for(R ll i=1,llim,rlim;i<=n;++i){
  26. ++l[llim=rd()];
  27. ++r[m+1-(rlim=rd())];
  28. for(R ll j=llim+1;j<=m-rlim;++j) ++mid[j];
  29. }
  30. for(R ll i=1;i<=m;++i){
  31. c[i][0]=c[i][i]=1; fac[i]=(fac[i-1]*i)%mod;
  32. for(R ll j=1;j<i;++j) c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
  33. }
  34. f[0][0][0]=1;
  35. for(R ll i=0;i<m;++i)
  36. for(R ll j=0;j<=i;++j)
  37. for(R ll k=0;k<=n;++k)
  38. if(f[i][j][k]){
  39. if(j+1>=l[i+1]) (f[i+1][j+1-l[i+1]][k+r[i+1]]+=f[i][j][k]*(c[j+1][l[i+1]]*fac[l[i+1]])%mod)%=mod;
  40. if(j>=l[i+1]) (f[i+1][j-l[i+1]][k+r[i+1]]+=f[i][j][k]*(c[j][l[i+1]]*fac[l[i+1]]*mid[i+1])%mod)%=mod;
  41. if(j>=l[i+1]&&k+r[i+1]) (f[i+1][j-l[i+1]][k+r[i+1]-1]+=f[i][j][k]*(c[j][l[i+1]]*fac[l[i+1]]%mod*(k+r[i+1])%mod)%mod)%=mod;
  42. }
  43. for(R ll i=0;i<=m;++i) (ans+=f[m][i][0])%=mod;
  44. printf("%lld\n",ans);
  45. return 0;
  46. }

[ 51Nod 1327 ] 棋盘游戏的更多相关文章

  1. 51nod 1327 棋盘游戏——延迟决策的dp

    题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1327 因为一列填1个或0个(或0个!!!),而一行不知填多少个,所 ...

  2. 51Nod 1327 棋盘游戏 —— 延迟DP

    题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1327 看博客:https://www.cnblogs.com/Na ...

  3. DP没入门就入土

    写在前面 记录最近刷的DP题 以及 打死都不可能想到状态设计DP系列 汇总 洛谷 P6082 [JSOI2015]salesman 树形\(\texttt{DP}\) + 优先队列 比较容易看出来这是 ...

  4. 【51Nod 1244】莫比乌斯函数之和

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1244 模板题... 杜教筛和基于质因子分解的筛法都写了一下模板. 杜教筛 ...

  5. 51Nod 1268 和为K的组合

    51Nod  1268  和为K的组合 1268 和为K的组合 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 给出N个正整数组成的数组A,求能否从中选出若干个,使 ...

  6. 51Nod 1428 活动安排问题

    51Nod   1428  活动安排问题 Link: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1428 1428 活 ...

  7. 51Nod 1278 相离的圆

    51Nod 1278 相离的圆 Link: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1278 1278 相离的圆 基 ...

  8. 【51Nod 1501】【算法马拉松 19D】石头剪刀布威力加强版

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1501 dp求出环状不连续的前缀和,剩下东西都可以算出来,比较繁琐. 时间 ...

  9. 【51Nod 1622】【算法马拉松 19C】集合对

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1622 简单题..直接暴力快速幂 #include<cstdio&g ...

随机推荐

  1. Java的动态代理(DynamicProxy)

    代理的概述 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理. 代理模式UML图 ...

  2. Json解析工具Jackson(使用注解)--jackson框架自定义的一些json解析注解

    Json解析工具Jackson(使用注解)--jackson框架自定义的一些json解析注解 @JsonIgnoreProperties 此注解是类注解,作用是json序列化时将Javabean中的一 ...

  3. nginx: 添加文件下载目录

    修改nginx.conf,添加如下行: location /file/ {    alias /usr/share/nginx/html/file/;    add_header Content-di ...

  4. Spring mvc+Easyui遇到的几个问题

    简单的一个数据表的增删查改的总体界面的展示效果例如以下图: 1.datagrid数据载入问题 datagrid通过url请求后台数据,总记录数和数据行的属性是固定死的.数据行是rows,总记录数为to ...

  5. Scala入门到精通——第十五节 Case Class与模式匹配(二)

    本节主要内容 模式匹配的类型 for控制结构中的模式匹配 option类型模式匹配 1. 模式的类型 1 常量模式 object ConstantPattern{ def main(args: Arr ...

  6. C#之选择排序

    算法描述 1.假定未排序序列中第一位为数组最小值,通过与后面的数值进行比较,找到未排序序列中最小值,与未排序序列第一位交换位置: 2.重复步骤一,对剩余未排序序列进行比较找出最小值,与未排序序列中第一 ...

  7. Android Path路径设置,针对error opening trace file:No such file or directory

    对于android的开发者来说,首先要做的就是环境变量的配置.学习过java的人都知道,java是须要配置环境变量的,那么android开发是否也须要我们配置环境变量呢?当然,安卓的环境变量须要我们配 ...

  8. 运行Java -jar somefile.jar时发生了什么(二)

    (6)Java.c中的LoadMainClass 位置jdk/src/share/bin/java.c 该方法负责载入main函数所在的类. 该方法首先载入sun.launcher.LauncherH ...

  9. Android showDialog时报错requestFeature() must be called before adding content

    View view = View.inflate(this, R.layout.layout_dialog, null); AlertDialog alertDialog = new AlertDia ...

  10. 洛谷[USACO06JAN]把牛Corral the Cows

    题目描述 约翰打算建一个围栏来圈养他的奶牛.作为最挑剔的兽类,奶牛们要求这个围栏必须是正方 形的,而且围栏里至少要有C< 500)个草场,来供应她们的午餐. 约翰的土地上共有C<=N< ...