BZOJ 3294: [Cqoi2011]放棋子(计数dp)
解题思路
设\(f[i][j][k]\)表示前\(k\)个颜色的棋子占领了\(i\)行\(j\)列的方案数,那么转移时可以枚举上一个颜色时占领的位置,\(f[i][j][k]=\sum\limits_{l=1}^n\sum\limits_{j=1}^mf[l][r][k-1]*C(n-l,i-l)*C(m-r,j-r)\),但发现这样会少一个\(k\)这种颜色占领的方案数,再设\(g[i][j][k]\)表示用相同颜色的\(k\)个棋子占领\(i\)行\(j\)列的方案数,而算\(g\)时可以考虑用总的情况减去不符合的情况,即\(g[i][j][k]=C(i*j,k)-g[l][r][k]*C(i,l)*C(j,r)\)。然后把\(g\)也算到\(f\)里去即可,时间复杂度\(O(n^2m^2c)\)
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define int long long 
using namespace std;
const int N=35;
const int MOD=1e9+9;
typedef long long LL;
inline int rd(){
	int x=0,f=1; char ch=getchar();
	while(!isdigit(ch)) f=ch=='-'?0:1,ch=getchar();
	while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
	return f?x:-x;
}
int n,m,c,cnt[15],C[N*N][N*N];
int f[N][N][15],g[N][N],ans;
inline void prework(){
	C[0][0]=1;
	for(int i=1;i<=n*m;i++){
		C[i][0]=1;
		for(int j=1;j<=i;j++)
			C[i][j]=(C[i-1][j-1]+C[i-1][j])%MOD;
	}
}
signed main(){
	n=rd(),m=rd(),c=rd(); prework();
	for(int i=1;i<=c;i++) cnt[i]=rd();
	f[0][0][0]=1;
	for(int o=1;o<=c;o++){
		memset(g,0,sizeof(g));
		for(int i=1;i<=n;i++)
			for(int j=1;j<=m;j++)if(i*j>=cnt[o]){
				g[i][j]=C[i*j][cnt[o]];
				for(int l=1;l<=i;l++)
					for(int r=1;r<=j;r++)if(i>l || j>r){
						g[i][j]-=(LL)g[l][r]*C[i][l]%MOD*C[j][r]%MOD;
						g[i][j]=(g[i][j]%MOD+MOD)%MOD;
					}
			}
		for(int i=1;i<=n;i++)
			for(int j=1;j<=m;j++)
				for(int l=0;l<i;l++)
					for(int r=0;r<j;r++)if((i-l)*(j-r)>=cnt[o])	{
						f[i][j][o]+=(LL)f[l][r][o-1]*g[i-l][j-r]%MOD*C[n-l][i-l]%MOD*C[m-r][j-r]%MOD;
						f[i][j][o]%=MOD;
					}
	}
//	for(int i=1;i<=n;i++)
//		for(int j=1;j<=m;j++)
//			for(int o=1;o<=c;o++)
//				printf("f[%d][%d][%d]=%d\n",i,j,o,f[i][j][o]);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			ans=(ans+f[i][j][c])%MOD;
	printf("%lld\n",ans);
	return 0;
}
BZOJ 3294: [Cqoi2011]放棋子(计数dp)的更多相关文章
- BZOJ 3294: [Cqoi2011]放棋子 计数 + 容斥 + 组合
		比较头疼的计数题. 我们发现,放置一个棋子会使得该棋子所在的1个行和1个列都只能放同种棋子. 定义状态 $f_{i,j,k}$ 表示目前已使用了 $i$ 个行,$j$ 个列,并放置了前 $k$ 种棋子 ... 
- 【BZOJ 3294】 3294: [Cqoi2011]放棋子 (DP+组合数学+容斥原理)
		3294: [Cqoi2011]放棋子 Description Input 输入第一行为两个整数n, m, c,即行数.列数和棋子的颜色数.第二行包含c个正整数,即每个颜色的棋子数.所有颜色的棋子总数 ... 
- BZOJ 3294: [Cqoi2011]放棋子
		3294: [Cqoi2011]放棋子 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 628 Solved: 238[Submit][Status] ... 
- [CQOI2011]放棋子 (DP,数论)
		[CQOI2011]放棋子 \(solution:\) 看到这道题我们首先就应该想到有可能是DP和数论,因为题目已经很有特性了(首先题面是放棋子)(然后这一题方案数很多要取模)(而且这一题的数据范围很 ... 
- P3158 [CQOI2011]放棋子(dp+组合数)
		P3158 [CQOI2011]放棋子 放棋子的顺序和方案数无关,所以可以从按颜色递推 设$f[u][p][k]$为放到第$u$种颜色,所剩空间$p*k$的方案数 $g[u][i][j]$表示第$u$ ... 
- 洛谷P3158 [CQOI2011]放棋子 组合数学+DP
		题意:在一个m行n列的棋盘里放一些彩色的棋子,使得每个格子最多放一个棋子,且不同颜色的棋子不能在同一行或者同一列.有多少祌方法? 解法:这道题不会做,太菜了qwq.题解是看洛谷大佬的. 设C是组合数, ... 
- [CQOI2011]放棋子 题解(dp+组合数学)
		Description Input 输入第一行为两个整数n, m, c,即行数.列数和棋子的颜色数. 第二行包含c个正整数,即每个颜色的棋子数. 所有颜色的棋子总数保证不超过nm. N,M<=3 ... 
- bzoj3294[Cqoi2011]放棋子 dp+组合+容斥
		3294: [Cqoi2011]放棋子 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 755 Solved: 294[Submit][Status] ... 
- bzoj千题计划261:bzoj3294: [Cqoi2011]放棋子
		http://www.lydsy.com/JudgeOnline/problem.php?id=3294 如果一个颜色的棋子放在了第i行第j列,那这种颜色就会占据第i行第j列,其他颜色不能往这儿放 设 ... 
随机推荐
- 16/8/23_CSS自动换行
			转载:http://blog.csdn.net/ye987987/article/details/8011875 自动换行问题,正常字符的换行是比较合理的,而连续的数字和英文字符常常将容器撑大,挺 ... 
- phpcms列表分页ajax加载更多
			1.在phpcms\modules\content\index.php文件中添加以下函数: /*列表分页ajax加载更多*/ public function homeajaxlist() { if( ... 
- docker ssh连接不上
			docker ssh连接报下面的错 Last login: Thu Apr 13 09:17:23 2017 from localhost Connection to 127.0.0.1 closed ... 
- css中一些文本属性的用法
			代码 /* text-transform用法 */ .p1 { /* 默认值 */ text-transform: none; } .p2 { /* 每个单词的首字母大写 */ text-transf ... 
- [烧脑时刻]EL表达式1分钟完事
			一天,程序员A问我,我们比比谁的知识点多,反应快.我回答:那就看谁最快用EL表达式的显示在页面上吧. 话不多说,计时开始. 项目的结构如上,大概就是一个Family的JavaBean,一个jsp页面, ... 
- smbcontrol - 向smbd或nmbd进程发送消息
			总览smbcontrol [ -i ] smbcontrol [ 目标 ] [ 消息类型 ] [ 参数 ] 描述这个工具是是Samba组件的一部分. smbcontrol是个很小的程序,用它可以向系统 ... 
- python常用函数 E
			endswith(str/tuple) 末尾元素匹配,可以传入tuple. 例子: enumerate(iterable) 可以跟踪集合元素索引,适用于迭代器. 例子: eval(str) 可以字符串 ... 
- 如何改变string中的字符值?
			string本身是不可变的,因此要改变string中字符,需要如下操作: str := “hello world” s := []byte(str) s[] = ‘o’ str = string(s) ... 
- poj 2505 乘法博弈论
			转自:http://hzwer.com/1921.html 题目大意: 题意:Stan从1开始,可以乘上2~9中任何一个数,Ollie也如此操作,只到某个人本回合的操作超过N为之..1<N< ... 
- 分布式架构的CAP原理
			CAP 定理的含义 一.分布式系统的三个指标 1998年,加州大学的计算机科学家 Eric Brewer 提出,分布式系统有三个指标. Consistency Availability Parti ... 
