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

P3158 [CQOI2011]放棋子

放棋子的顺序和方案数无关,所以可以从按颜色递推

设$f[u][p][k]$为放到第$u$种颜色,所剩空间$p*k$的方案数

$g[u][i][j]$表示第$u$种颜色占据$i*j$空间的方案数,可以预处理

$g[u][i][j]=\binom{i*j}{c[u]}-\sum_{p=1}^{i}\sum_{k=1}^{j}g[u][p][k]*\binom{i}{i-p}*\binom{j}{j-k}*[p<i||j<k]$

$f[u][p][k]=\sum_{i=1}^{n-p}\sum_{j=1}^{m-k}f[u-1][p+i][k+j]*\binom{p+i}{i}*\binom{k+j}{j}*g[u][i][j]$

复杂度$O(n^2m^2C)$

#include<iostream>
#include<cstdio>
#include<cstring>
#define ri register int
using namespace std;
const int P=1000000009;
int t,n,m,s,C[903][903],g[12][32][32],f[12][32][32],ans;
int main(){
    scanf("%d%d%d",&n,&m,&t);
    for(ri i=0;i<=n*m;++i){
        C[i][0]=1;
        for(int j=1;j<=i;++j) C[i][j]=(C[i-1][j]+C[i-1][j-1])%P;
    }f[0][n][m]=1;
    for(ri u=1;u<=t;++u){
        scanf("%d",&s);
        for(ri i=1;i<=n;++i)
            for(ri j=1;j<=m;++j) if(s<=i*j){
                g[u][i][j]=C[i*j][s];
                for(ri p=1;p<=i;++p)
                    for(ri k=1;k<=j;++k) if(p<i||k<j){
                        ri v=1ll*C[i][i-p]*C[j][j-k]%P;
                        (g[u][i][j]-=1ll*g[u][p][k]*v%P-P)%=P;
                    }
            }
        for(ri i=1;i<=n;++i)
            for(ri j=1;j<=m;++j)
                if(s<=i*j)
                    for(ri p=i;p<=n;++p)
                        for(ri k=j;k<=m;++k){
                            ri v=1ll*C[p][i]*C[k][j]%P*g[u][i][j]%P;
                            (f[u][p-i][k-j]+=1ll*f[u-1][p][k]*v%P)%=P;
                        }
    }
    for(ri i=0;i<=n;++i)
        for(ri j=0;j<=m;++j)
            (ans+=f[t][i][j])%=P;
    printf("%d",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/kafuuchino/p/11545230.html

时间: 2024-11-06 09:36:10

P3158 [CQOI2011]放棋子(dp+组合数)的相关文章

BZOJ 3294: [Cqoi2011]放棋子

3294: [Cqoi2011]放棋子 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 628  Solved: 238[Submit][Status][Discuss] Description Input 输入第一行为两个整数n, m, c,即行数.列数和棋子的颜色数.第二行包含c个正整数,即每个颜色的棋子数.所有颜色的棋子总数保证不超过nm. Output 输出仅一行,即方案总数除以 1,000,000,009的余数. Sample Input

[CQOI2011] 放棋子 - 计数dp

在一个 \(m\) 行 \(n\) 列的棋盘里放一些彩色的棋子,使得每个格子最多放一个棋子,且不同颜色的棋子不能在同一行或者同一列,有多少种方法? Solution 设 \(f[i][j][k]\) 表示用前 \(k\) 种颜色的棋子,占领了 \(i\) 行 \(j\) 列的方案数 设 \(g[i][j][k]\) 表示用任意 \(k\) 个同色棋子占领 \(i\) 行 \(j\) 列的方案数,则考虑总方案数 - 实际上有没有被占领的行或列的方案数,则 \[g[i][j][k]=C_{ij}^k

[题解] [CQOI2011] 放棋子

题面 题解 为了练习计数而做 注意到一种颜色占据的行, 列其他的颜色不能放 又考虑到我们并不需要知道哪些行哪些列选了, 只需要知道还有几行几列没选即可 于是有 \(f[i][j][k]\) 代表前 \(i\) 种颜色选完之后, 还有 \(j\) 行没选, \(k\) 列没选的方案数 \(g[i][j][k]\) 代表, \(i\) 个棋子, 放在 \(j\) 行 \(k\) 列中并且没有空行空列的方案数 \(cnt_i\) 代表颜色为 \(i\) 的棋子有几个 有 \[ \displaystyl

[CQOI2011]放棋子

想到了50%吧算是. f[i][j][k]表示,前i种,占了j行k列.方案数. 发现,转移要处理:"用c个棋子,占据n行m列"的方案数. 设g[i][j][k]表示,i行j列用k个棋子占的方案数.直接处理复杂度爆炸. 然后我就mengbier了. 考虑大力容斥: 也即,总方案数-不合法方案数(不能覆盖完全) g[i][j][k]=C(i*j,k)-∑l∑r:g[l][r][k]*C(i,l)*C(j,r) (i*j>=k&&l<=i&&j&l

LibreOJ #2061. 「HAOI2016」放棋子

二次连通门 : LibreOJ #2061. 「HAOI2016」放棋子 /* LibreOJ #2061. 「HAOI2016」放棋子 MDZZ ... 错排 + 高精 */ #include <iostream> #include <cstdio> #include <vector> #include <iomanip> #include <cassert> #include <algorithm> #define int64 l

HDU 4248 A Famous Stone Collector(DP + 组合数)

题目链接:点击打开链接 思路:DP + 组合数. 用d[i][j]表示前第i种颜色的石头, 已经用了j个的方法数, 每次枚举第i种石头放多少个, 假设放k个, 那么相当于从j个位置中选k个, 预处理组合数就行了. 细节参见代码: #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<vector&

[HAOI2016]放棋子

题意 Here 思考 看第一眼:状压dp,再看范围gg 第二眼:普通dp,貌似可以直接递推? 其实就是个很裸的错排问题,写个博客顺便复习下~ 错排问题就是说一个 \(n\) 的排列,每个元素都满足 \(a[i] != i\),求方案数 记 \(f[n]\) 为 \(n\) 的错排方案数,我们可以考虑递推: 放第 \(n\) 个元素,有 \(n-1\) 种方法 假设第 \(n\) 个元素放在了 \(p\) 位置,那么放编号为 \(p\) 的元素: 放在 \(n\) 位置,对于剩下 \(n-2\)

bzoj4563[Haoi2016]放棋子

bzoj4563[Haoi2016]放棋子 题意: 给你一个N*N的矩阵,每行有一个障碍,数据保证任意两个障碍不在同一行,任意两个障碍不在同一列.要求你放N枚棋子(障碍的位置不能放棋子),也满足每行只有一枚棋子,每列只有一枚棋子的限制,求有多少种方案.N≤200. 题解: 发现在障碍在什么位置和答案无关.因此可以把棋子摆成左上-右下对角线,然后就是错排问题(一个长度为n的排列,要求每个元素不能放在与自己编号相同的位置上,问有多少种方案满足条件)了.错排公式:f[i]=(f[i-1]+f[i-2]

hdu 4945 2048 (dp+组合数)

2048 Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 840    Accepted Submission(s): 199 Problem Description Teacher Mai is addicted to game 2048. But finally he finds it's too hard to get 2048.