BZOJ3294: [Cqoi2011]放棋子

来源:互联网 发布:2015中国财政支出数据 编辑:程序博客网 时间:2024/04/28 11:31

一开始一直以为可以不放完棋子…


n、m都不大,可以考虑DP
因为每行、每列只能放一种颜色的棋子,所以考虑把棋盘独立成n行m列,将这些行和列分给每种颜色的棋子
定义:
f[i][j]表示第k种棋子占据i行j列有多少种合法的放法,
g[k][i][j]表示前k种棋子占据i行j列有多少种合法的放法
f的时候可以用容斥,用所有的放法减去所有不合法的放法,预处理一下组合数
然后fg合并

tips:最后输出答案要计算未占满所有行列的情况

code:

#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long long#define lowbit(x) x&(-x) using namespace std;const int maxn = 32;const int maxk = 12;const int maxm = 910;const ll Mod = 1e9+9;int n,m,N,v[maxn];ll c[maxm][maxm];ll f[maxn][maxn],g[maxk][maxn][maxn];int main(){    c[0][0]=1;    for(int i=0;i<maxm;i++)    {        c[i][0]=1;        for(int j=1;j<=i;j++)             c[i][j]=(c[i-1][j-1]+c[i-1][j])%Mod;    }    scanf("%d%d%d",&n,&m,&N);    for(int i=1;i<=N;i++) scanf("%d",&v[i]);    g[0][0][0]=1ll;    for(int k=1;k<=N;k++)    {        for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)f[i][j]=0ll;        for(int i=1;i<=n;i++)            for(int j=1;j<=m;j++)            {                if(i*j>=v[k])                {                    f[i][j]=c[i*j][v[k]];                    for(int x=1;x<=i;x++)                        for(int y=1;y<=j;y++)                        {                            if(x==i&&y==j) break;                            if(f[x][y])                            (f[i][j]-=f[x][y]*c[i][x]%Mod*c[j][y]%Mod)%=Mod;                        }                }            }        for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)        {            for(int x=1;x<=i;x++)            for(int y=1;y<=j;y++)                if(f[x][y])                (g[k][i][j]+=g[k-1][i-x][j-y]                *f[x][y]%Mod*c[i][x]%Mod*c[j][y]%Mod)%=Mod;        }    }    ll ret=0;    for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)         (ret+=g[N][i][j]*c[n][i]%Mod*c[m][j]%Mod)%=Mod;    printf("%lld\n",ret);    return 0;}
0 0
原创粉丝点击