3294: [Cqoi2011]放棋子

Description

Input

输入第一行为两个整数nmc,即行数、列数和棋子的颜色数。第二行包含c个正整数,即每个颜色的棋子数。所有颜色的棋子总数保证不超过nm

Output

输出仅一行,即方案总数除以 1,000,000,009的余数。

Sample Input

4 2 2
3 1

Sample Output

8

HINT

N,M<=30 C<=10 总棋子数<=250

Source

【分析】

  表示一开始看错题ORZ。。以为相同颜色的不能放一起【这样怎么做??

  然后就是其实题目不是这样的、、、

  DP[i][j][k]表示决策到第k种颜色,前k种颜色一共占了i行j列的方案数。

  枚举第k行占的行数和列数,ii,jj,那么dp[i][j][k]=f[i-ii][j-jj][k-1]*B[ii][jj][k]*C[n-(i-ii)][ii]*C[m-(j-jj)][jj]

  其中C是组合数,B[ii][jj][k]表示用ii行jj列填k个东西的方案(注意B数组要满足每一行每一列都有东西,不然好像很容易算重复)

  对于B数组,我一开始用了两种方法求,都不对(超容易算重复smg,然后很内伤)

  最后感觉只有枚举这一种方法是可以求出来的,

  就是递推 B[x][y][z]=C[x*y][k]-sigma(B[i][j][k]*C[x][i]*C[y][j]) (1<=i<=x&&1<=j<=y&&(i!=x||j!=y))

  【这里是容斥吧?

  组合数学没学好所以我这题又做了很久ORZ。。

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define Mod 1000000009
#define Maxn 910
#define LL long long LL sm[],f[][][];
int n,m,c; LL C[Maxn][Maxn]; void get_c()
{
memset(C,,sizeof(C));
for(int i=;i<=n*m;i++) C[i][]=;
for(int i=;i<=n*m;i++)
for(int j=;j<=i;j++) C[i][j]=(C[i-][j-]+C[i-][j])%Mod;
} LL B[][][];
LL get_B(int x,int y,int z)
{
if(B[x][y][z]!=-) return B[x][y][z];
if(x==&&sm[z]==) {B[x][y][z]=;return ;}
if(sm[z]<x||sm[z]<y||x*y<sm[z]) {B[x][y][z]=;return ;}
LL ans=;
ans=C[x*y][sm[z]];
for(int i=;i<=x;i++)
for(int j=;j<=y;j++)
{
if(i==x&&j==y) continue;
// ans++;
LL X=get_B(i,j,z)%Mod,
Y=(C[x][i]*C[y][j])%Mod;
ans=ans-X*Y;ans%=Mod;
ans=(ans+Mod)%Mod;
}
// printf("B[%d][%d][%d]=%d\n",x,y,z,ans);
/*for(int i=1;i<=z;i++)
ans=(ans+get_B(x-1,y,z-i)*C[y][i])%Mod;
printf("B[%d][%d][%d]=%d\n",x,y,z,ans);*/ /*ans=C[n*m][x];ans%=Mod;
ans-=C[(n-1)*m][x]*n;ans%=Mod;
ans-=C[n*(m-1)][x]*m;ans%=Mod;
ans+=C[(n-1)*(m-1)][x]*n*m;ans%=Mod;
ans=(ans+Mod)%Mod;*/
B[x][y][z]=ans;
return ans;
} int main()
{
scanf("%d%d%d",&n,&m,&c);
for(int i=;i<=c;i++) scanf("%d",&sm[i]);
get_c();
memset(f,,sizeof(f));
memset(B,-,sizeof(B));
f[][][]=;
LL ans=;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
for(int k=;k<=c;k++) get_B(i,j,k);
for(int k=;k<=c;k++)
{
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
{
for(int ii=;ii<=i;ii++)
for(int jj=;jj<=j;jj++)
{
LL X=(C[n-(i-ii)][ii]*C[m-(j-jj)][jj])%Mod,
Y=(f[i-ii][j-jj][k-]*B[ii][jj][k])%Mod;
f[i][j][k]=(f[i][j][k]+X*Y)%Mod;
} // f[i][j][k]=(f[i][j][k]+(C[n-(i-ii)][ii]*C[m-(j-jj)][jj])%Mod*(f[i-ii][j-jj][k-1]*C[ii*jj][sm[k]])%Mod)%Mod;
if(k==c) ans=(ans+f[i][j][k])%Mod;
// printf("f[%d][%d][%d]=%lld\n",i,j,k,f[i][j][k]);
}
}
printf("%lld\n",ans);
return ;
}

屏蔽掉的是一开始两种错误方法。。

2017-03-21 08:28:26

【BZOJ 3294】 3294: [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】[Cqoi2011]放棋子

    题解: 一道很经典的组合数+dp 首先考虑f[i][j][k]表示前k种颜色正好占据了i行j列 转移的话就是枚举第k种颜色占据了几行几列 通过自身转移 然后其在内部的相对顺序是不确定的所以要乘以组合数 ...

  4. BZOJ 3294: [Cqoi2011]放棋子

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

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

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

  6. [CQOI2011]放棋子 (DP,数论)

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

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

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

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

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

  9. BZOJ3294: [Cqoi2011]放棋子

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

随机推荐

  1. 【CodeForces】866D. Buy Low Sell High

    [题意]已知n天股价,每天可以买入一股或卖出一股或不作为,最后必须持0股,求最大收益. [算法]堆 贪心? [题解] 不作为思想:[不作为=买入再卖出] 根据不作为思想,可以推出中转站思想. 中转站思 ...

  2. 【CodeForces】790 C. Bear and Company 动态规划

    [题目]C. Bear and Company [题意]给定大写字母字符串,交换相邻字符代价为1,求最小代价使得字符串不含"VK"子串.n<=75. [算法]动态规划 [题解 ...

  3. 【BZOJ】4555: [Tjoi2016&Heoi2016]求和 排列组合+多项式求逆 或 斯特林数+NTT

    [题意]给定n,求Σi=0~nΣj=1~i s(i,j)*2^j*j!,n<=10^5. [算法]生成函数+排列组合+多项式求逆 [题解]参考: [BZOJ4555][Tjoi2016& ...

  4. 【洛谷 P4134】 [BJOI2012]连连看(费用流)

    题目链接 首先是可以\(O(n^2)\)枚举出所有符合要求的点对的,然后考虑建图. 还是拆点把每个点拆成入点和出点,源点连入点,出点连汇点,流量都是1,费用都是0. 然后对于没对符合要求的\((x,y ...

  5. 天梯赛 L2-012 关于堆的判断 (二叉树)

    将一系列给定数字顺序插入一个初始为空的小顶堆H[].随后判断一系列相关命题是否为真.命题分下列几种: "x is the root":x是根结点: "x and y ar ...

  6. 解决爬虫时网站采用gb2312编码所遇到的乱码问题!

    import requests from bs4 import BeautifulSoupall_url = 'http://www.7160.com/qingchunmeinv/' # 请求头 he ...

  7. 26、Python的可变类型和不可变类型?

    Python的每个对象都分为可变和不可变 可变:列表.字典 不可变:数字.字符串.元祖 对不可变类型的变量重新赋值,实际上是重新创建一个不可变类型的对象,并将原来的变量重新指向新创建的对象(如果没有其 ...

  8. three.js轨道控制器OrbitControls.js

    https://blog.csdn.net/qq_37338983/article/details/78575333 文章地址

  9. perl6正则 2: 字母,数字,空格,下划线, 字符集

    数字, 字母, 下划线 在perl6中, 如果是 数字, 字母, 下划线, 在正则里可以正接写上. > so / True > so 'perl6_' ~~ /_/ True > 非 ...

  10. Machine Learning系列--CRF条件随机场总结

    根据<统计学习方法>一书中的描述,条件随机场(conditional random field, CRF)是给定一组输入随机变量条件下另一组输出随机变量的条件概率分布模型,其特点是假设输出 ...