题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1327

看博客:https://www.cnblogs.com/Narh/p/9791875.html

思路就是按列DP,如果不是必须填就先空下这一列,记录一下目前有多少可用的空列,遇到一个 l 的结束时就从中选一些列放上棋子,并乘个排列;

对于 r,方案数在当前列体现,所以要记录当前列可填的位置;

注意别漏了状态,当前可转移的状态是填 l,填 r,不填,填在不是 l 也不是 r 的地方四种转移;

还有各种细节...全仰仗 Narh 提点;

呆滞了半小时...一对拍就发现...在算 A 的地方别忘了写 (ll) !!!

好题啊!

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int const xn=,xm=,mod=1e9+;
int n,m,l[xn],r[xn],f[xm][xm][xm],jc[xm],jcn[xm],sl[xm],sr[xm];
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=(ret<<)+(ret<<)+ch-'',ch=getchar();
return f?ret:-ret;
}
ll pw(ll a,int b)
{
ll ret=;
for(;b;b>>=,a=(a*a)%mod)
if(b&)ret=(ret*a)%mod;
return ret;
}
void init()
{
jc[]=;
for(int i=;i<=m;i++)jc[i]=((ll)jc[i-]*i)%mod;
jcn[m]=pw(jc[m],mod-);
for(int i=m-;i>=;i--)jcn[i]=((ll)jcn[i+]*(i+))%mod;
}
int A(int n,int m){return (ll)jc[n]*jcn[n-m]%mod;}//(ll)!!!
void upt(int &x,int y){x+=y; while(x>=mod)x-=mod; while(x<)x+=mod;}
int main()
{
n=rd(); m=rd(); init();
for(int i=;i<=n;i++)l[i]=rd(),r[i]=rd(),sl[l[i]]++,sr[m-r[i]+]++;
for(int i=;i<=m;i++)sr[i]+=sr[i-];
f[][][]=;
for(int i=,num=;i<m;i++,num=num+sl[i])//列
for(int j=max(,sl[i+]-);j<=i-num;j++)//剩余
for(int k=;k<=min(i,n);k++)//填r
{
if(!f[i][j][k])continue;
if(sl[i+])
upt(f[i+][j+-sl[i+]][k],(ll)f[i][j][k]*A(j+,sl[i+])%mod);
//,printf("f[%d][%d][%d]=%d A(%d,%d)=%lld f[%d][%d][%d]=%d\n",i,j,k,f[i][j][k],j+1,sl[i+1],A(j+1,sl[i+1]),i+1,j+1-sl[i+1],k,f[i+1][j+1-sl[i+1]][k]);//l
else upt(f[i+][j+][k],f[i][j][k]);//
if(sr[i+]>k&&j>=sl[i+])
upt(f[i+][j-sl[i+]][k+],(ll)f[i][j][k]*A(j,sl[i+])%mod*(sr[i+]-k)%mod);
//,printf("sr=%d k=%d f[%d][%d][%d]=%d f[%d][%d][%d]=%d\n",sr[i+1],k,i,j,k,f[i][j][k],i+1,j-sl[i+1],k+1,f[i+1][j-sl[i+1]][k+1]);//r(+l)
if(num-sr[i+]&&j>=sl[i+])
upt(f[i+][j-sl[i+]][k],(ll)f[i][j][k]*A(j,sl[i+])%mod*(num-sr[i+])%mod);
//,printf("!l!r:f[%d][%d][%d]=%d A=%lld k=%d f[%d][%d][%d]=%d\n",i,j,k,f[i][j][k],A(j,sl[i+1]),num-sr[i+1],i+1,j-sl[i+1],k,f[i+1][j-sl[i+1]][k]);//!l,!r (+l)
// printf("f[%d][%d][%d]=%d\n",i,j,k,f[i][j][k]);
}
int ans=;
for(int j=;j<=m-*n;j++)upt(ans,f[m][j][n]);
//,printf("f[%d][%d][%d]=%d\n",m,j,n,f[m][j][n]);
printf("%d\n",ans);
return ;
}

51Nod 1327 棋盘游戏 —— 延迟DP的更多相关文章

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

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

  2. [ 51Nod 1327 ] 棋盘游戏

    \(\\\) \(Description\) 给出一张\(N\times M\)的棋盘,每个格子最多放置一个棋子,一个合法的放置方案需满足: 每列至多放置一个棋子 对于第\(i\)行,前\(L_i\) ...

  3. 51nod 1353 树 | 树形DP经典题!

    51nod 1353 树 | 树形DP好题! 题面 切断一棵树的任意条边,这棵树会变成一棵森林. 现要求森林中每棵树的节点个数不小于k,求有多少种切法. 数据范围:\(n \le 2000\). 题解 ...

  4. 51nod 1636 教育改革 | DP

    51nod 1636 教育改革 | DP 题面 最近A学校正在实施教育改革. 一个学年由n天组成.A学校有m门课程,每天学生必须学习一门课,一门课程必须在一天内学习完.在学习完第i门课程后,学生们会收 ...

  5. 51nod 1021 石子归并(dp)

    51nod 1021 石子归并 题解:从i到j合并的最小值:dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j] + sum[j] - sum[i-1]); 最 ...

  6. 51nod 1183 - 编辑距离 - [简单DP][编辑距离问题][Levenshtein距离问题]

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1183 编辑距离,又称Levenshtein距离(也叫做Edi ...

  7. 51nod 1406 位运算/dp

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1406 1406 与查询 题目来源: CodeForces 基准时间限制: ...

  8. 51NOD 1202 子序列个数 DP

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1202&judgeId=225600 这题看起来挺复杂,但是真正的 ...

  9. 51nod 1201 整数划分 dp

    1201 整数划分 基准时间限制:1 秒 空间限制:131072 KB   收藏  关注 将N分为若干个不同整数的和,有多少种不同的划分方式,例如:n = 6,{6} {1,5} {2,4} {1,2 ...

随机推荐

  1. UNIDAC不能识别CLIENTDATASET的TSINGLEFIELD

    UNIDAC不能识别CLIENTDATASET的TSINGLEFIELD FIREDAC,UNIDAC这些通用的数据引擎,对某种数据库的支持,细节方面总有BUG. UNIDAC6.2.8发现不能识别C ...

  2. Chrome/谷歌开发者工具分析

    Chrome/谷歌开发者工具还是要好好掌握一下,对于前端开发超级有用:https://developers.google.com/web/tools/chrome-devtools/ 1.js内存使用 ...

  3. BUPT复试专题—内存分配(2014-2)

    题目描述 在操作系统中,内存分配是非常重要的工作.己知内存空间由N个内存块组成,这些内存块从1到N编号.进行内存分配时,操作系统将选择一块大小足够的内存全部分配给请求内存的进程.例如,当进程请求10M ...

  4. [Cypress] install, configure, and script Cypress for JavaScript web applications -- part1

    Despite the fact that Cypress is an application that runs natively on your machine, you can install ...

  5. Netty3 源代码分析 - NIO server绑定过程分析

    Netty3 源代码分析 - NIO server绑定过程分析      一个框架封装的越好,越利于我们高速的coding.可是却掩盖了非常多的细节和原理.可是源代码可以揭示一切. 服务器端代码在指定 ...

  6. eclipse 配置执行hadoop 2.7 程序样例參考步骤

    前提:你搭建好了hadoop 2.x的linux环境,并可以成功执行.还有就是window可以訪问到集群.over 1. hfds-site.xml 添加属性:关闭集群的权限校验.windows的用户 ...

  7. 常用linux系统监控命令

    一.内存监控 监控内存的使用状态是非常重要的,通过监控有助于了解内存的使用状态,比如内存占用是否正常,内存是否紧缺等等,监控内存最常使用的命令有free.vmstat.top等 1.1 free $ ...

  8. 菜鸟系列之C/C++经典试题(三)

    设计包括min函数的栈 题目:定义栈的数据结构,要求加入一个min函数,可以得到栈的最小元素.要求函数min.push以及pop的时间复杂度都是O(1). 分析:这是2006年google的一道面试题 ...

  9. openwrt: sysupgrade

    sysupgrade 用法: sysupgrade [...] sysupgrade [-q] [-i] 升级选项: -d 重启前等待 delay 秒 -f 从 .tar.gz (文件或链接) 中恢复 ...

  10. [Selenium]通过Selenium实现在当前浏览器窗口点击一个图标之后,弹出另外一个窗口,关闭这个窗口,再回到原来的窗口进行操作

    public void clickReportIcon(){ String initialWindowHandle = driver.getWindowHandle(); //保存原始的浏览器窗口 p ...