[CQOI2011]放棋子



$ solution: $

看到这道题我们首先就应该想到有可能是DP和数论,因为题目已经很有特性了(首先题面是放棋子)(然后这一题方案数很多要取模)(而且这一题的数据范围很小)

但真正实用的还是分析题目性质:这一道题我们仔细读题,可以发现每一种棋子的影响是相对独立的(即我们只需要知道这种颜色的棋子占了多少行列,而不需要知道它占的哪一行那一列)(这个可以画画图自证一下),而且每一种颜色占多少行和多少列也有方案数(我占两行两列,可以用两个棋子,也可以用三个或四个棋子)(而且即使如此,它还是相对独立的)

所以我们不难列出一种DP状态转移,我用 $ f[i][j][k] $ 表示前k种棋子占了i行j列的方案数

$ f[i][j][k] = \sum \limits_{l = 0}^{i - 1} \sum \limits_{r = 0}^{j - 1}f[l][r][k - 1] \times g[i-l][j-r][a[k]] $ (用 a[k] 枚棋子占 (i - l) 行 (j - r) 列的方案数)

$ \times C_{n - l}^{i - l}\times C_{m - r}^{j - r} $ (因为独立,我们可以任选 $ a[k] $ 枚棋子占用的行和列)

但是我们发现这样转移的时候,我们还需要知道(用 a[k] 枚棋子占 (i - l) 行 (j - r) 列的方案数)这个东西其实我们可以在前面就先预处理出来,状态转移十分好写!



$ code: $

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set> #define ll long long
#define db double
#define rg register int using namespace std; const int mod=1e9+9; int n,m,c,ans;
int g[35][35];
int C[905][905];
int f[31][31][11]; inline int qr(){
char ch;
while((ch=getchar())<'0'||ch>'9');
int res=ch^48;
while((ch=getchar())>='0'&&ch<='9')
res=res*10+(ch^48);
return res;
} int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
n=qr(); m=qr(); c=qr();
for(rg i=0;i<=900;++i)C[i][0]=1;
for(rg i=1;i<=900;++i)
for(rg j=1;j<=i;++j)
C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
f[0][0][0]=1;
for(rg k=1;k<=c;++k){
rg x=qr();
for(rg i=1;i<=n;++i){
for(rg j=1;j<=m;++j){
g[i][j]=0;
if(i*j<x)continue;
g[i][j]=C[i*j][x];
for(rg l=1;l<=i;++l){
for(rg r=1;r<=j;++r){
if(l==i&&r==j)continue;
g[i][j]-=(ll)g[l][r]*C[i][l]%mod*C[j][r]%mod;
if(g[i][j]<mod)g[i][j]+=mod;
}
}
}
}
for(rg i=1;i<=n;++i){
for(rg j=1;j<=m;++j){
for(rg l=0;l<i;++l){
for(rg r=0;r<j;++r){
if((i-l)*(j-r)<x)continue;
f[i][j][k]+=(ll)f[l][r][k-1]*g[i-l][j-r]%mod*C[n-l][i-l]%mod*C[m-r][j-r]%mod;
if(f[i][j][k]>mod)f[i][j][k]-=mod;
}
}
}
}
}
for(rg i=1;i<=n;++i)
for(rg j=1;j<=m;++j)
(ans+=f[i][j][c])%=mod;
printf("%d\n",ans);
return 0;
}

[CQOI2011]放棋子 (DP,数论)的更多相关文章

  1. bzoj3294[Cqoi2011]放棋子 dp+组合+容斥

    3294: [Cqoi2011]放棋子 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 755  Solved: 294[Submit][Status] ...

  2. [CQOI2011]放棋子--DP

    题目描述: 输入格式 输入第一行为两个整数n, m, c,即行数.列数和棋子的颜色数.第二行包含c个正整数,即每个颜色的棋子数.所有颜色的棋子总数保证不超过nm.N,M<=30 C<=10 ...

  3. 【BZOJ 3294】 3294: [Cqoi2011]放棋子 (DP+组合数学+容斥原理)

    3294: [Cqoi2011]放棋子 Description Input 输入第一行为两个整数n, m, c,即行数.列数和棋子的颜色数.第二行包含c个正整数,即每个颜色的棋子数.所有颜色的棋子总数 ...

  4. P3158 [CQOI2011]放棋子(dp+组合数)

    P3158 [CQOI2011]放棋子 放棋子的顺序和方案数无关,所以可以从按颜色递推 设$f[u][p][k]$为放到第$u$种颜色,所剩空间$p*k$的方案数 $g[u][i][j]$表示第$u$ ...

  5. [洛谷P3158] [CQOI2011]放棋子

    洛谷题目链接:[CQOI2011]放棋子 题目描述 在一个m行n列的棋盘里放一些彩色的棋子,使得每个格子最多放一个棋子,且不同 颜色的棋子不能在同一行或者同一列.有多少祌方法?例如,n=m=3,有两个 ...

  6. BZOJ 3294: [Cqoi2011]放棋子

    3294: [Cqoi2011]放棋子 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 628  Solved: 238[Submit][Status] ...

  7. bzoj千题计划261:bzoj3294: [Cqoi2011]放棋子

    http://www.lydsy.com/JudgeOnline/problem.php?id=3294 如果一个颜色的棋子放在了第i行第j列,那这种颜色就会占据第i行第j列,其他颜色不能往这儿放 设 ...

  8. BZOJ3294: [Cqoi2011]放棋子

    Description   Input 输入第一行为两个整数n, m, c,即行数.列数和棋子的颜色数.第二行包含c个正整数,即每个颜色的棋子数.所有颜色的棋子总数保证不超过nm. Output 输出 ...

  9. BZOJ3294: [Cqoi2011]放棋子(计数Dp,组合数学)

    题目链接 解题思路: 发现一个性质,如果考虑一个合法的方案可以将行和列都压到一起,也就是说,在占用行数和列数一定的情况下,行列互换是不会影响答案的,那么考虑使用如下方程: $f[i][j][k]$为占 ...

随机推荐

  1. spring之跨模块引用配置文件

    1.导入包或加入依赖关系 2.引入spring配置文件: <?xml version="1.0" encoding="UTF-8"?> <be ...

  2. semantic segmentation with deeplearning

    a 2017 guide to semantic segmentation with deep learning paper: http://blog.qure.ai/notes/semantic-s ...

  3. mysql 常用命令导入导出修改root密码

    MySQL 忘记口令的解决办法如果 MySQL 正在运行,首先杀之: killall -TERM mysqld. 启动 MySQL :mysql --skip-grant-tables & / ...

  4. hdu 3727 Jewel (可持久化线段树+bit)

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=3727 题意: 对一段序列进行四种操作: Insert x :在序列尾部插入一个x: Query_1 s ...

  5. day27 封装

    广义上的面向对象的封装: 代码的保护,面向对象思想本身就是一种封装 只让自己的对象调用自己类的方法 狭义的封装: 面向对象的三大特性之一,其他两个是继承和多态. 属性和方法都可以藏起来不让你看到 cl ...

  6. 树剖模板(洛谷P3384 【模板】树链剖分)(树链剖分,树状数组,树的dfn序)

    洛谷题目传送门 仍然是一个板子. 不过蒟蒻去学了一下BIT维护区间修改区间求和,常数果真十分优秀 设数列为\(a_i\),差分数组\(d_ i=a_ i-a_ {i-1}\),前缀和\(s_i=\su ...

  7. LOJ #6270. 数据结构板子题 (离线+树状数组)

    题意 有 \(n\) 个区间,第 \(i\) 个区间是 \([l_i,r_i]\) ,它的长度是 \(r_i-l_i\) . 有 \(q\) 个询问,每个询问给定 \(L,R,K\) ,询问被 \([ ...

  8. Leetcode 347.前K个高频元素 By Python

    给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums = [1], ...

  9. 【BZOJ2299】[HAOI2011]向量(数论)

    [BZOJ2299][HAOI2011]向量(数论) 题面 BZOJ 洛谷 题解 首先如果我们的向量的系数假装可以是负数,那么不难发现真正有用的向量只有\(4\)个,我们把它列出来.\((a,b)(a ...

  10. AT1219 歴史の研究 解题报告

    AT1219 歴史の研究 题意 给定一个长为\(n\)的序列\(\{a\}\),询问区间\(a*cnt_a\)的最大值,即某个值乘上出现次数 回退莫队板子 只右移右指针和左指针每次回到块结尾即可. C ...