zoukankan      html  css  js  c++  java
  • BZOJ3294: [Cqoi2011]放棋子

    Description

     

    Input

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

    Output

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

    Sample Input

    4 2 2
    3 1

    Sample Output

    8

    HINT

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

    我们发现因为不能同行同列颜色不同的格子,所以我们相当于是将整张棋盘的行列分给这C种棋子。

    这样我们设g[n][m][k]表示前k种棋子放完,占据了n行m列的方案数。g[n][m][k]=sum(g[n-x][n-y][k-1]*C(x,n)*C(y,n)*f[x][y][k])。

    其中f[x][y][k]表示第i种棋子刚好放在了x行y列棋盘的方案数,要求每行每列都至少有一个棋子。

    不难发现f数组可以用容斥原理来计算,枚举有多少行列没放棋子,转移方程也很简单。

    #include<cstdio>
    #include<cctype>
    #include<queue>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define ren for(int i=first[x];i;i=next[i])
    using namespace std;
    inline int read() {
        int x=0,f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    typedef long long ll;
    const int maxn=35;
    const int maxm=255;
    const int mod=1000000009;
    ll C[1010][1010],f[maxn][maxn][11],g[maxn][maxn][11];
    int n,m,c,A[maxn];
    void init() {
        C[0][0]=1;
        rep(i,1,1000) {
            C[i][0]=C[i][i]=1;
            rep(j,1,i-1) C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
        }
    }
    int main() {
        n=read();m=read();c=read();
        rep(i,1,c) A[i]=read();
        init();
        rep(i,1,n) rep(j,1,m) rep(k,1,c) if(i<=A[k]&&j<=A[k]&&i*j>=A[k]){
            f[i][j][k]=C[i*j][A[k]];ll& ans=f[i][j][k];
            rep(i1,1,i) rep(j1,1,j) if(i1!=i||j1!=j) (ans-=(f[i1][j1][k]*C[i][i1]%mod)*C[j][j1])%=mod;
            ans=(ans%mod+mod)%mod;
        }
        g[0][0][0]=1;
        rep(i,1,n) rep(j,1,m) rep(k,1,c) {
            ll& ans=g[i][j][k];
            rep(i1,1,i) rep(j1,1,j) (ans+=(((f[i1][j1][k]*C[i][i1]%mod)*C[j][j1])%mod)*g[i-i1][j-j1][k-1])%=mod;
        }
        ll ans=0;
        rep(i,1,n) rep(j,1,m) (ans+=C[n][i]*C[m][j]%mod*g[i][j][c]%mod)%=mod;
        printf("%lld
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    (OK) CORE nodes access Internet—虚拟节点访问互联网—commands
    Open VSwitch—离开VMware的SDN之父Martin Casado是神马大神
    (OK-half) Fedora23——Docker——CORE—testing
    【codeforces 752B】Santa Claus and Keyboard Check
    【codeforces 752C】Santa Claus and Robot
    【codeforces 752E】Santa Claus and Tangerines
    【codeforces 548E】Mike and Foam
    【codeforces 752D】Santa Claus and a Palindrome
    【codeforces 752F】Santa Clauses and a Soccer Championship
    【codeforces 546A】Soldier and Bananas
  • 原文地址:https://www.cnblogs.com/wzj-is-a-juruo/p/5303374.html
Copyright © 2011-2022 走看看