【BZOJ3294】放棋子(动态规划,容斥,组合数学)

题面

BZOJ

洛谷

题解

如果某一行某一列被某一种颜色给占了,那么在考虑其他行的时候可以直接把这些行和这些列给丢掉。

那么我们就可以写出一个\(dp\)

设\(f[i][r][c]\)表示考虑了前\(i\)种颜色,还剩下\(r\)行\(c\)列没被染色。

那么转移的时候枚举一下当前颜色染了\(a\)行\(b\)列转移就好了。

但是问题来了,怎么计算用\(K\)个棋子恰好覆盖\(a\)行\(b\)列的方案数呢?

恰好很不好算,那么我们换一下,至多覆盖了\(a\)行\(b\)列的方案数。

那么这个很容易算出来是\(C_{ab}^{K}\)。

那么我们可以容斥计算恰好覆盖了\(a\)行\(b\)列的方案数。

我们在计算\(a,b\)的时候就已经可以算出来恰好覆盖了\(l,l<a\)行\(r,r<b\)列的方案数,

那么直接拿总数减去不合法的就好了。

接下来就是一个很简单的\(dp\)了,稍微用组合数算一下即可。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll long long
#define MOD 1000000009
#define MAX 35
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
void add(int &x,int y){x+=y;if(x>=MOD)x-=MOD;}
int n,m,c,ans;
int f[MAX][MAX][MAX],a[MAX];
int jc[MAX*MAX],jv[MAX*MAX],inv[MAX*MAX];
int g[MAX][MAX][MAX];
int C(int n,int m){if(m>n)return 0;return 1ll*jc[n]*jv[m]%MOD*jv[n-m]%MOD;}
int main()
{
n=read();m=read();c=read();
for(int i=1;i<=c;++i)a[i]=read();
jc[0]=inv[0]=inv[1]=jv[0]=1;
for(int i=1;i<=n*m;++i)jc[i]=1ll*jc[i-1]*i%MOD;
for(int i=2;i<=n*m;++i)inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;
for(int i=1;i<=n*m;++i)jv[i]=1ll*jv[i-1]*inv[i]%MOD;
for(int i=1;i<=c;++i)
for(int j=1;j<=n;++j)
for(int k=1;k<=m;++k)
{
if(j*k<a[i])continue;
g[i][j][k]=C(j*k,a[i]);
for(int l=1;l<=j;++l)
for(int r=1;r<=k;++r)
if(l!=j||r!=k)add(g[i][j][k],MOD-1ll*C(j,l)*C(k,r)%MOD*g[i][l][r]%MOD);
}
f[0][0][0]=1;
for(int i=1;i<=c;++i)
for(int j=1;j<=n;++j)
for(int k=1;k<=m;++k)
for(int a=1;a<=j;++a)
for(int b=1;b<=k;++b)
add(f[i][j][k],1ll*g[i][a][b]*f[i-1][j-a][k-b]%MOD*C(n-j+a,a)%MOD*(C(m-k+b,b))%MOD);
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)add(ans,f[c][i][j]);
printf("%d\n",ans);
return 0;
}

【BZOJ3294】放棋子(动态规划,容斥,组合数学)的更多相关文章

  1. BZOJ 3294: [Cqoi2011]放棋子 计数 + 容斥 + 组合

    比较头疼的计数题. 我们发现,放置一个棋子会使得该棋子所在的1个行和1个列都只能放同种棋子. 定义状态 $f_{i,j,k}$ 表示目前已使用了 $i$ 个行,$j$ 个列,并放置了前 $k$ 种棋子 ...

  2. 【BZOJ4559】[JLoi2016]成绩比较 动态规划+容斥+组合数学

    [BZOJ4559][JLoi2016]成绩比较 Description G系共有n位同学,M门必修课.这N位同学的编号为0到N-1的整数,其中B神的编号为0号.这M门必修课编号为0到M-1的整数.一 ...

  3. 2015 asia xian regional F Color (容斥 + 组合数学)

    2015 asia xian regional F Color (容斥 + 组合数学) 题目链接http://codeforces.com/gym/100548/attachments Descrip ...

  4. BZOJ2839:集合计数(容斥,组合数学)

    Description 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得它们的交集的元素个数为K,求取法的方案数,答案模1000000007. ...

  5. 容斥 + 组合数学 ---Codeforces Round #317 A. Lengthening Sticks

    Lengthening Sticks Problem's Link: http://codeforces.com/contest/571/problem/A Mean: 给出a,b,c,l,要求a+x ...

  6. Gym 100548F Color 给花染色 容斥+组合数学+逆元 铜牌题

    Problem F. ColorDescriptionRecently, Mr. Big recieved n flowers from his fans. He wants to recolor th ...

  7. [CTS2019]随机立方体(容斥+组合数学)

    这题七次方做法显然,但由于我太菜了,想了一会发现也就只会这么多,而且别的毫无头绪.发现直接做不行,那么,容斥! f[i]为至少i个极值的方案,然后这里需要一些辅助变量,a[i]表示选出i个三维坐标均不 ...

  8. 51nod1667-概率好题【容斥,组合数学】

    正题 题目链接:http://www.51nod.com/Challenge/Problem.html#problemId=1667 题目大意 两个人. 第一个人有\(k_1\)个集合,第\(i\)个 ...

  9. JZYZOJ1544 [haoi2016T2]放棋子 错排公式 组合数学 高精度

    http://172.20.6.3/Problem_Show.asp?ID=1544&a=ProbNF 看了题解才意识到原题有错排的性质(开始根本不知道错排是什么). 十本不同的书放在书架上. ...

  10. CF 317 A. Lengthening Sticks(容斥+组合数学)

    传送门:点我 A. Lengthening Sticks  time limit per test        1 second You are given three sticks with po ...

随机推荐

  1. Python自动化运维

    一.DNS域名轮询业务监控 链接:https://www.cnblogs.com/baishuchao/articles/9128953.html 二.文件内容差异对比方法 链接:https://ww ...

  2. TPO-22 C1 Complain about a biased article

    /* 加粗:语音部分 * 红色:单词部分 * 斜体:语法部分 * 下划线:信号词/句 */ 第 1 段 1.Listen to a conversation between a student and ...

  3. Siki_Unity_7-4_高自由度沙盘游戏地图生成_MineCraft_Uniblocks插件(可拓展)

    Unity 7-4 高自由度沙盘游戏地图生成 MineCraft (插件Uniblocks) 任务1&2&3&4 素材 && 课程演示 && 课 ...

  4. HPUX系统启动后主机名为unknown的解决办法

    HPUX系统启动完成后,主机名为unknown,查看/etc/rc.log出现如下报错:   unknown:[/]grep -i error /etc/rc.log /sbin/rc1.d/S320 ...

  5. kali linux执行apt-get update失败(数字签名过期)

    想要安装某个软件,执行apt-get update 失败,出现下面的错误: 自己查看了更新源是没有问题的,根据提示的错误google了一下,发现是数字签名过期了. 执行下面命令: apt-key ad ...

  6. mv命令详解

    基础命令学习目录首页 原文链接:https://www.cnblogs.com/piaozhe116/p/6084214.html mv命令是move的缩写,可以用来移动文件或者将文件改名(move ...

  7. redis解决商品秒杀问题

    博主最近在项目中遇到了抢购问题!现在分享下.抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少("超卖" ...

  8. iOS 开发学习-import和include的区别

    //当我们在代码中使用两次#include的时候会报错:因为#include相当于拷贝头文件中的声明内容,所以会报重复定义的错误 //但是使用两次#import的话,不会报错,所以他可以解决重复导入的 ...

  9. 私人助手(Alpha)版使用说明

    私人助手使用说明 私人助手这款软件是通过添加事件提醒,提醒你在合适的时间做该做的事,可以选择有多种提醒模式. 目前实现了对事件的添加和提醒功能,软件现在的情况如下: 1.添加事件 2.删除事件 3.事 ...

  10. 为什么要读这本书《java编程思想》

    在学校学习编程语言只是浅显的了解,不理解的的东西有很多 ,想通过这本书对java语言有更深的理解,对于以后的学习和工作会有很大的好处.与其了了草草的看你一些书,知其然而不知其所以然,这不是我想要的学习 ...