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. 【BZOJ】3963: [WF2011]MachineWorks

    [题意]给定n台在时间di可以买入的机器,pi买入,可在任意时间ri卖出,买入和卖出之间的持有时间每天产生gi金钱,任意时间至多持有一台机器.给定初始钱数c和总天数T,求最大收益.n<=10^5 ...

  2. ajax做显示信息以后用ajax、Bootstrp做弹窗显示信息详情

    1.用ajax做弹窗显示信息详情 nation.php <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&qu ...

  3. CentOS 6.5 安装 MongoDB

    1. 配置 yum 新建 /etc/yum.repos.d/mongodb-org-3.4.repo 文件,使用以下配置:(适用于 MongoDB 3.0 以后版本) [mongodb-org-3.4 ...

  4. php菜刀分析学习

    这里以eval为例 我们知道, php中的eval能把字符串当代码执行: eval('phpcode'); 注意, 这里的代码要有分号结尾, 我们测试: 我们创建一个最简单的SHELL: <?p ...

  5. windos8设置cpu数量和内存大小

    转自:http://smilejay.com/2012/03/windows_cpu_memory_setting/ Windows 8(测试版)在作为Xen Guest中的benchmark测试.我 ...

  6. xss 过滤

    一. xss过滤 用户通过Form获取展示在终端, 提交数据,Form验证里面加入xss验证(对用户提交的内容验证是否有关键标签) from django.conf.urls import url f ...

  7. Linux下的格式化字符串漏洞利用姿势

    linux最早的漏洞防护机制nx-stack刚刚出现后就有人想出了突破方法.那就是只有栈是不可执行,而除了栈以外的其他地方还是可以执行的,只要把返回地址执行别的地方就可以. 一.格式化字符串漏洞 格式 ...

  8. MVC公开课 – 1.基础 (2013-3-15广州传智MVC公开课)

    1.MVC设计模式 Model 是指 要处理的业务代码和数据操作代码 View 视图 主要是指的 跟用户打交道 并能够展示数据 Controller 看成是 Model和View的桥梁 优点: 1.1 ...

  9. Java学习(API及Object类、String类、StringBuffer字符串缓冲区)

    一.JAVA的API及Object类 1.API 概念: Java 的API(API: Application(应用) Programming(程序) Interface(接口)) Java API就 ...

  10. 【LOJ】 #2132. 「NOI2015」荷马史诗

    题解 k叉哈夫曼树,但是没有了二叉那样的最后一定能合并成一个树根的优秀性质,我们就不断模拟操作看看到了哪一步能用的节点数< k,然后先拿这些节点数合并起来 然后就可以k个k个合并了,大小一样先拿 ...