[ 51Nod 1327 ] 棋盘游戏
\(\\\)
\(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\)
#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 60
#define M 210
#define R register
#define gc getchar
#define mod 1000000007
using namespace std;
typedef long long ll;
ll fac[M]={1},c[M][M]={1},ans;
ll n,m,l[M],r[M],mid[M],f[M][M][N];
inline ll rd(){
ll x=0; char c=gc();
while(!isdigit(c)) c=gc();
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}
return x;
}
int main(){
n=rd(); m=rd();
for(R ll i=1,llim,rlim;i<=n;++i){
++l[llim=rd()];
++r[m+1-(rlim=rd())];
for(R ll j=llim+1;j<=m-rlim;++j) ++mid[j];
}
for(R ll i=1;i<=m;++i){
c[i][0]=c[i][i]=1; fac[i]=(fac[i-1]*i)%mod;
for(R ll j=1;j<i;++j) c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
}
f[0][0][0]=1;
for(R ll i=0;i<m;++i)
for(R ll j=0;j<=i;++j)
for(R ll k=0;k<=n;++k)
if(f[i][j][k]){
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;
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;
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;
}
for(R ll i=0;i<=m;++i) (ans+=f[m][i][0])%=mod;
printf("%lld\n",ans);
return 0;
}
[ 51Nod 1327 ] 棋盘游戏的更多相关文章
- 51nod 1327 棋盘游戏——延迟决策的dp
题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1327 因为一列填1个或0个(或0个!!!),而一行不知填多少个,所 ...
- 51Nod 1327 棋盘游戏 —— 延迟DP
题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1327 看博客:https://www.cnblogs.com/Na ...
- DP没入门就入土
写在前面 记录最近刷的DP题 以及 打死都不可能想到状态设计DP系列 汇总 洛谷 P6082 [JSOI2015]salesman 树形\(\texttt{DP}\) + 优先队列 比较容易看出来这是 ...
- 【51Nod 1244】莫比乌斯函数之和
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1244 模板题... 杜教筛和基于质因子分解的筛法都写了一下模板. 杜教筛 ...
- 51Nod 1268 和为K的组合
51Nod 1268 和为K的组合 1268 和为K的组合 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 给出N个正整数组成的数组A,求能否从中选出若干个,使 ...
- 51Nod 1428 活动安排问题
51Nod 1428 活动安排问题 Link: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1428 1428 活 ...
- 51Nod 1278 相离的圆
51Nod 1278 相离的圆 Link: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1278 1278 相离的圆 基 ...
- 【51Nod 1501】【算法马拉松 19D】石头剪刀布威力加强版
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1501 dp求出环状不连续的前缀和,剩下东西都可以算出来,比较繁琐. 时间 ...
- 【51Nod 1622】【算法马拉松 19C】集合对
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1622 简单题..直接暴力快速幂 #include<cstdio&g ...
随机推荐
- qemu-guest-agent简介
经常使用vmWare的同学都知道有vmware-tools这个工具,这个安装在vm内部的工具,可以实现宿主机与虚拟机的通讯,大大增强了虚拟机的性能与功能, 如vmware现在的Unity mode下可 ...
- 《Noisy Activation Function》噪声激活函数(一)
本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/51736830 Noisy Activa ...
- 一个DBA对于开发人员使用MySQL的tips
http://neoremind.net/2011/06/%E4%B8%80%E4%B8%AAdba%E5%AF%B9%E4%BA%8E%E5%BC%80%E5%8F%91%E4%BA%BA%E5%9 ...
- Codeforces Round #240 (Div. 2) D
, b2, ..., bl (1 ≤ b1 ≤ b2 ≤ ... ≤ bl ≤ n) is called good if each number divides (without a remainde ...
- noip模拟赛 都市
分析:是一道非常有意思的题,30分的暴力的话枚举每个位置是什么数,然后排个序,用map判一下重就好了,比较麻烦. 满分做法显然不可能讨论每个位置所有的情况,肯定是有规律的,现将这n*(n-1)/2个数 ...
- 采药 2005年NOIP全国联赛普及组&疯狂的采药
时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师.为此,他想拜附近最有威望 ...
- QT .pro文件的学习收获
1. 载pro文件预定义宏: CONFIG(debug,debug|release){ DEFINES+=__DEBUG__ }else{ DEFINES+=__RELEASE__ macx:DEST ...
- Redis3.0集群方案分析
在Redis3.0集群出来之前,大家都对作者antirez寄予厚望,因为Redis从来没有让我们失望过.现在Redis3.0集群出来了,网上出了很多评论文章,都说他的功能多么强大,包括下面这张图是彻底 ...
- SQLalchemy 查询总结
#简单查询 print(session.query(User).all()) print(session.query(User.name, User.fullname).all()) print(se ...
- CentOS 7: 设置时区和时间
查看当前时区和时间 $ date $ ls -l /etc/localtime 查看所有可用时区 $ timedatectl list-timezones | grep Asia 设置时区 $ tim ...