洛谷题目链接:[CQOI2011]放棋子

题目描述

在一个m行n列的棋盘里放一些彩色的棋子,使得每个格子最多放一个棋子,且不同

颜色的棋子不能在同一行或者同一列。有多少祌方法?例如,n=m=3,有两个白棋子和一

个灰棋子,下面左边两祌方法都是合法的,但右边两祌都是非法的。

输入输出格式

输入格式:

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

输出格式:

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

输入输出样例

输入样例#1:

4 2 2

3 1

输出样例#1:

8

说明

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

题解: 一道\(DP\)的好题.

定义状态\(f[i][j][k]\)表示用前\(k\)种颜色占领了任意\(i\)行\(j\)列.

设\(a[k]\)表示第\(k\)种颜色的棋子的个数.

转移很显然是$$f[i][j][k]=\sum_{l=0}{i-1}\sum_{r=0}{j-1}f[l][r][k-1]C_{n-l}{i-l}*C_{m-r}{j-r}用a[k]个棋子占领任意i-l行j-r列的方案数$$

那么我们再定义状态\(g[i][j][k]\)表示用\(k\)个相同颜色的棋子占领任意\(i\)行\(j\)列的方案数,直接算不太好算,我们可以考虑容斥:$$g[i][j][k]=C_{ij}k-\sum_{l=0}{i}\sum_{r=0}{j}g[l][r][k]*C_{i}{l}C_{j}^{r},(l \not= i \ ||\ r \not= j)$$

预处理了\(g\)数组,就可以对\(f\)数组转移了:$$f[i][j][k]=\sum_{l=0}{i-1}\sum_{r=0}{j-1}f[l][r][k-1]C_{n-l}{i-l}*C_{m-r}{j-r}g[i-l][j-r][a[k]]$$

因为不一定要放满整个棋盘,所以$$ans=\sum_{l=1}n\sum_{r=1}mf[i][j][c]$$

其实还可以用滚动数组滚掉\(g\)数组的最后一维.

// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
const int N = 30+5;
const int COL = 10+5;
const int K = 250+5;
const int mod = 1e9+9; int n, m, C, a[N], c[1000][1000], ans = 0;
int f[N][N][COL], g[N][N][1000];
// f : k types of col occupied any i lines, j rows
// g : same type k chess piece occupied any i lines, j rows int main(){
cin >> n >> m >> C;
for(int i = 1; i <= n; i++) cin >> a[i];
f[0][0][0] = c[0][0] = 1;
for(int i = 1; i <= 900; i++){
c[i][0] = 1;
for(int j = 1; j <= i; j++) c[i][j] = (c[i-1][j]+c[i-1][j-1])%mod;
}
for(int k = 1; k <= C; k++)
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++){
if(a[k] > i*j) continue; int res = 0;
g[i][j][a[k]] = c[i*j][a[k]];
for(int l = 1; l <= i; l++)
for(int r = 1; r <= j; r++)
if(l < i || r < j) (res += 1ll*c[i][l]*c[j][r]%mod*g[l][r][a[k]]%mod) %= mod;
g[i][j][a[k]] = (g[i][j][a[k]]-res+mod)%mod;
}
for(int k = 1; k <= C; k++)
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
for(int l = 0; l < i; l++)
for(int r = 0; r < j; r++)
(f[i][j][k] += 1ll*c[n-l][i-l]*c[m-r][j-r]%mod*g[i-l][j-r][a[k]]%mod*f[l][r][k-1]%mod) %= mod;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) (ans += f[i][j][C]) %= mod;
cout << ans << endl;
return 0;
}

[洛谷P3158] [CQOI2011]放棋子的更多相关文章

  1. 洛谷P3158 [CQOI2011]放棋子 组合数学+DP

    题意:在一个m行n列的棋盘里放一些彩色的棋子,使得每个格子最多放一个棋子,且不同颜色的棋子不能在同一行或者同一列.有多少祌方法? 解法:这道题不会做,太菜了qwq.题解是看洛谷大佬的. 设C是组合数, ...

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

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

  3. 洛谷 P3182 [HAOI2016]放棋子(高精度,错排问题)

    传送门 解题思路 不会错排问题的请移步——错排问题 && 洛谷 P1595 信封问题 这一道题其实就是求对于每一行的每一个棋子都放在没有障碍的地方的方案数. 因为障碍是每行.每列只有一 ...

  4. 洛谷P3182 [HAOI2016]放棋子

    P3182 [HAOI2016]放棋子 题目描述 给你一个N*N的矩阵,每行有一个障碍,数据保证任意两个障碍不在同一行,任意两个障碍不在同一列,要求你在这个矩阵上放N枚棋子(障碍的位置不能放棋子),要 ...

  5. 题解 P3158 [CQOI2011]放棋子

    题解 本题是一个 \(DP\) 加 容斥,容斥的式子很好推,重点是如何想到和如何推出 \(DP\) 部分的式子. 因为不同种颜色的棋子不能放在同一行或同一列,所以不同种的棋子是相对独立的. 据此,我们 ...

  6. 洛谷 P3182 [HAOI2016]放棋子(错排问题)

    题面 luogu 题解 裸的错排问题 错排问题 百度百科:\(n\)个有序的元素应有\(n!\)个不同的排列,如若一个排列使得所有的元素不在原来的位置上,则称这个排列为错排:有的叫重排.如,1 2的错 ...

  7. P3158 [CQOI2011]放棋子

    传送门 题解(因为公式太多懒得自己抄写一遍了--) //minamoto #include<bits/stdc++.h> #define ll long long #define R re ...

  8. BZOJ 3294: [Cqoi2011]放棋子

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

  9. bzoj3294[Cqoi2011]放棋子 dp+组合+容斥

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

随机推荐

  1. HDU 3853 LOOPS 期望dp

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3853 LOOPS Time Limit: 15000/5000 MS (Java/Others)Me ...

  2. 二路归并排序java实现

    二路归并排序:其核心思想时将问题一分为二,并递归调用一分为二方法,使问题分割到不能再分各的原子问题,然后再归并,从实现原子问题开始,层层向上归并,最终解决整体问题.即所谓“分而治之,万流归一” 二路归 ...

  3. grunt入门讲解4:如何创建task(任务)

    每当运行Grunt时, 你可以为其指定一个或多个任务, 这些任务用于告诉Grunt你想要它做什么事情. 如果你没有指定一个任务,并且你已经定义一个名为 "default" 的任务, ...

  4. java9初探

    最近研究了一下java9的新特性,也看完了<Modularity Programming in Java 9>,有一些收获写博客记录一下. 1.java9初探

  5. 使用docker-compose编排django、mysql实战

    背景: 本萌最近在部署自己开发的项目的时候发现同一套代码上传到服务器上后,部分功能莫名其妙的有点问题,服务器的各项配置都没有做过变动,所以想把项目转战到docker. 奈何刚接触docker,很多地方 ...

  6. ACM数论之旅5---数论四大定理(你怕不怕(☆゚∀゚)老实告诉我)

    (本篇无证明,想要证明的去找度娘)o(*≧▽≦)ツ ----------数论四大定理--------- 数论四大定理: 1.威尔逊定理 2.欧拉定理 3.孙子定理(中国剩余定理) 4.费马小定理 (提 ...

  7. Opera官网打不开 下载Opera最新版本的实际地址

    目前Opera官网可以打开,但是点下载时就会出错,国内无法访问Opera的下载地址,无法通过官网直接下载Opera浏览器.下面提供下载的方式. 一.通过官方的ftp站点下载 FTP地址为 http:/ ...

  8. BZOJ5312 冒险(线段树)

    记录区间and/or,修改时如果对整个区间影响都相同就打标记,否则递归.复杂度不太会证. #include<iostream> #include<cstdio> #includ ...

  9. BZOJ3162 独钓寒江雪(哈希+树形dp)

    数独立集显然是可以树形dp的,问题在于本质不同. 假设已经给树确立了一个根并且找到了所有等效(注意是等效而不是同构)子树,那么对转移稍加修改使用隔板法就行了. 关键在于找等效子树.首先将树的重心(若有 ...

  10. aliyun阿里云alibabaMaven仓库地址——加速你的maven构建

    在maven的settings.xml 文件里 搜索  mirrors   ,把下面内容添加在其子节点内 <mirror> <id>nexus-aliyun</id> ...