BZOJ3294: [Cqoi2011]放棋子(计数Dp,组合数学)
解题思路:
发现一个性质,如果考虑一个合法的方案可以将行和列都压到一起,也就是说,在占用行数和列数一定的情况下,行列互换是不会影响答案的,那么考虑使用如下方程:
$f[i][j][k]$为占领了i行j列使用了前k种颜色,由于要求全部用完,不需要枚举放入多少,考虑一个一个来添加颜色。考虑添加第k种颜色:
因为第k种颜色一定是占据了新的一行一列,所以加入第k种颜色后的行数=加入之前的行数+第k种颜色占据的行数,列数同理。
设第k种颜色的棋子有a个,那么我们只需要知道用A种颜色占据i行j列的方案数,设为$g[i][j][A]$这个可以使用容斥
转移即为$g[i][j][A]=C_{i*j}^A-\limits\sum_{a=1}^{i}\limits\sum_{b=1}^{j}g[a][b][A]*C_i^a*C_j^b$发现和A毛关系没有就舍去了这一维。
所以最后的转移就是:
$f[i][j][k]=\limits\sum_{a=1}^{i}\limits\sum_{b=1}^{j}f[i-a][i-b][k-1]*g[a][b]*C_{n-i+a}^{a}*C_{m-j+b}^{b}$
答案就是i,j的累和。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
typedef long long lnt;
const lnt mod=(lnt)(1e9+);
lnt f[][][];
lnt g[][];
int num[];
lnt C[][];
int n,m,c;
void get_g(int k)
{
memset(g,,sizeof(g));
int A=num[k];
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
if(i*j>=A)
{
g[i][j]=C[i*j][A];
for(int a=;a<=i;a++)
{
for(int b=;b<=j;b++)
{
if(a==i&&b==j)continue;
(g[i][j]-=g[a][b]*C[i][a]%mod*C[j][b]%mod)%=mod;
}
}
}
}
}
return ;
}
void init(void)
{
C[][]=;
for(int i=;i<=;i++)
{
C[i][]=;
for(int j=;j<=i;j++)
{
C[i][j]=(C[i-][j-]+C[i-][j])%mod;
}
}
return ;
}
int main()
{
scanf("%d%d%d",&n,&m,&c);
for(int i=;i<=c;i++)scanf("%d",&num[i]);
init();
f[][][]=;
for(int k=;k<=c;k++)
{
get_g(k);
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
if(i*j<num[k])continue;
for(int a=i;a<=n;a++)
{
for(int b=j;b<=m;b++)
{
(f[a][b][k]+=f[a-i][b-j][k-]*g[i][j]%mod*C[n-a+i][i]%mod*C[m-b+j][j]%mod)%=mod;
}
}
}
}
}
lnt ans();
for(int i=;i<=n;i++)for(int j=;j<=m;j++)(ans+=f[i][j][c])%=mod;
printf("%lld\n",(ans%mod+mod)%mod);
return ;
}
BZOJ3294: [Cqoi2011]放棋子(计数Dp,组合数学)的更多相关文章
- 【BZOJ 3294】 3294: [Cqoi2011]放棋子 (DP+组合数学+容斥原理)
3294: [Cqoi2011]放棋子 Description Input 输入第一行为两个整数n, m, c,即行数.列数和棋子的颜色数.第二行包含c个正整数,即每个颜色的棋子数.所有颜色的棋子总数 ...
- [CQOI2011]放棋子 题解(dp+组合数学)
Description Input 输入第一行为两个整数n, m, c,即行数.列数和棋子的颜色数. 第二行包含c个正整数,即每个颜色的棋子数. 所有颜色的棋子总数保证不超过nm. N,M<=3 ...
- BZOJ 3294: [Cqoi2011]放棋子(计数dp)
传送门 解题思路 设\(f[i][j][k]\)表示前\(k\)个颜色的棋子占领了\(i\)行\(j\)列的方案数,那么转移时可以枚举上一个颜色时占领的位置,\(f[i][j][k]=\sum\lim ...
- bzoj3294[Cqoi2011]放棋子 dp+组合+容斥
3294: [Cqoi2011]放棋子 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 755 Solved: 294[Submit][Status] ...
- [CQOI2011]放棋子 (DP,数论)
[CQOI2011]放棋子 \(solution:\) 看到这道题我们首先就应该想到有可能是DP和数论,因为题目已经很有特性了(首先题面是放棋子)(然后这一题方案数很多要取模)(而且这一题的数据范围很 ...
- bzoj千题计划261:bzoj3294: [Cqoi2011]放棋子
http://www.lydsy.com/JudgeOnline/problem.php?id=3294 如果一个颜色的棋子放在了第i行第j列,那这种颜色就会占据第i行第j列,其他颜色不能往这儿放 设 ...
- P3158 [CQOI2011]放棋子(dp+组合数)
P3158 [CQOI2011]放棋子 放棋子的顺序和方案数无关,所以可以从按颜色递推 设$f[u][p][k]$为放到第$u$种颜色,所剩空间$p*k$的方案数 $g[u][i][j]$表示第$u$ ...
- BZOJ3294: [Cqoi2011]放棋子
Description Input 输入第一行为两个整数n, m, c,即行数.列数和棋子的颜色数.第二行包含c个正整数,即每个颜色的棋子数.所有颜色的棋子总数保证不超过nm. Output 输出 ...
- BZOJ 3294: [Cqoi2011]放棋子 计数 + 容斥 + 组合
比较头疼的计数题. 我们发现,放置一个棋子会使得该棋子所在的1个行和1个列都只能放同种棋子. 定义状态 $f_{i,j,k}$ 表示目前已使用了 $i$ 个行,$j$ 个列,并放置了前 $k$ 种棋子 ...
随机推荐
- 兔子--Android Support v4包丢失的解决的方法
在开发中,Android Support v4包丢失的解决的方法: Project->properties->Java Build Path->Libraries->Add E ...
- Linux怎样改动root用户的password
Linux系统的root账号是很重要的一个账号.也是权限最大的一个账号,可是有时候忘了rootpassword怎么办?总不能重装系统吧,这个是下下策.事实上Linux系统中,假设忘记了root账号pa ...
- 从Oracle Database 角度来看浪潮天梭K1主机的操作系统选择
背景: 浪潮天梭k1主机.事实上分好几个类别: K1-950 intel 安腾cpu K1-930 intel 安腾cpu K1-910 intel 安腾cpu K1-800 intel 志强cpu ...
- SQL Server 2008 备份数据库
1.打开SQL , 找到要备份的数据库 , 右键 >> 任务 >>备份 2.弹出 [ 备份数据库对话框 ] ,如图: 3.点击加入 [ button ] . 例如以下图: 4. ...
- MDNS DDoS 反射放大攻击——攻击者假冒被攻击者IP向网络发送DNS请求,域名为“_services._dns-sd._udp.local”,这将引起本地网络中所有提供服务的主机都向被攻击者IP发送DNS响应,列举网络中所有服务
MDNS Reflection DDoS 2015年3月,有报告叙述了mDNS 成为反射式和放大式 DDoS 攻击中所用媒介的可能性,并详述了 mDNS 反射式攻击的原理和相应防御方式.Q3,Akam ...
- 3.c语言结构体成员内存对齐详解
一.关键一点 最关键的一点:结构体在内存中是一个矩形,而不是一个不规则形状 二.编程实战 #include <stdlib.h> #include <stdio.h> stru ...
- OLTP 与 OLAP
OLTP:On-Line Transaction Processing(联机事务处理过程).也称为面向交易的处理过程,其基本特征是前台接收的用户数据可以立即传送到计算中心进行处理,并在很短的时间内给出 ...
- HibernateProperties 配置属性
Hibernate properties Hibernate配置属性 属性名 用途hibernate.dialect ;一个Hibernate Dialect类名允许Hibernate针对特定的关系数 ...
- strlen() 和 sizeof() 的区别
1.strlen() 时函数,他在程序运行时才能计算.它的参数类型要求时 char *,且必须是以'/0'结尾.数组在传入时已经退化为指针.它的作用是返回数组中字符串的长度. 2.sizeof()时运 ...
- Oracle 流程控制语句
分为选择语句循环语句两大类:一 选择语句1 if then ...end;set serveroutput on declare var_name1 varchar2(50):='East'; var ...