【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. c语言数字图像处理(六):二维离散傅里叶变换

    基础知识 复数表示 C = R + jI 极坐标:C = |C|(cosθ + jsinθ) 欧拉公式:C = |C|ejθ 有关更多的时域与复频域的知识可以学习复变函数与积分变换,本篇文章只给出DF ...

  2. 用编程方式编写Babylon格式的宇宙飞船3D模型

    使用上一篇文章(https://www.cnblogs.com/ljzc002/p/9353101.html)中提出的方法,编写一个简单的宇宙飞船3D模型,在这篇文章中对模型制作流程和数学计算步骤进行 ...

  3. Unity3D Shader 学习笔记(二):ShaderLab的结构和基本属性

    (一) ShaderLab: 什么是ShaderLab: Unity3D支持的Shader种类包括: 1.Surface Shader:表面着色器 2.Vertex & Fragment Sh ...

  4. opengl绘制三角形

    顶点数组对象:Vertex Array Object,VAO 顶点缓冲对象:Vertex Buffer Object,VBO 索引缓冲对象:Element Buffer Object,EBO或Inde ...

  5. RenderSprite小记

    类型定义: /** @private */ public static const IMAGE:int = 0x01; /** @private */ public static const ALPH ...

  6. javascript实现对html便签等字符的转义

    参考链接:https://www.jb51.net/article/152700.htm 请访问以上链接. 本人纯搬迁,防止原作者删除. <script> var HtmlUtil = { ...

  7. 新手Python第二天(存储)

    Python 列表的创建 创建一个空列表 例如:fruit=[]  创建一个有元素的列表 例如:fruit=['apple','banana','cherry'] 创建嵌套列表 例如:fruit=[[ ...

  8. iOS 模块化、组件化方案探索(利用cocoapods 、git 创建私有仓库)

    来自bang's blog http://blog.cnbang.net/tech/3080/ 模块化 简单来说,模块化就是将一个程序按照其功能做拆分,分成相互独立的模块,以便于每个模块只包含与其功能 ...

  9. C++ Style Languages: C++, Objective-C, Java, C#

    Hyperpolyglot.org From Hyperpolyglot.org C++ Style Languages: C++, Objective-C, Java, C# a side-by-s ...

  10. [BUAA OO]第四次博客作业

      一.      测试与正确性论证的区别 在最后一个单元的OO作业中,我们主要进行了代码的测试与正确性论证工作.这俩者在作业中的体现分别是junit单元测试以及jsf论述语言.这两者在java代码开 ...