• [CQOI2011]放棋子 (DP,数论)


    [CQOI2011]放棋子



    $ solution: $

    看到这道题我们首先就应该想到有可能是DP和数论,因为题目已经很有特性了(首先题面是放棋子)(然后这一题方案数很多要取模)(而且这一题的数据范围很小)

    但真正实用的还是分析题目性质:这一道题我们仔细读题,可以发现每一种棋子的影响是相对独立的(即我们只需要知道这种颜色的棋子占了多少行列,而不需要知道它占的哪一行那一列)(这个可以画画图自证一下),而且每一种颜色占多少行和多少列也有方案数(我占两行两列,可以用两个棋子,也可以用三个或四个棋子)(而且即使如此,它还是相对独立的)

    所以我们不难列出一种DP状态转移,我用 $ f[i][j][k] $ 表示前k种棋子占了i行j列的方案数

    $ f[i][j][k] = sum limits_{l = 0}^{i - 1} sum limits_{r = 0}^{j - 1}f[l][r][k - 1] imes g[i-l][j-r][a[k]] $ (用 a[k] 枚棋子占 (i - l) 行 (j - r) 列的方案数)

    $ imes C_{n - l}^{i - l} imes C_{m - r}^{j - r} $ (因为独立,我们可以任选 $ a[k] $ 枚棋子占用的行和列)

    但是我们发现这样转移的时候,我们还需要知道(用 a[k] 枚棋子占 (i - l) 行 (j - r) 列的方案数)这个东西其实我们可以在前面就先预处理出来,状态转移十分好写!



    $ code: $

    #include<iostream>
    #include<cstdio>
    #include<iomanip>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<ctime>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<map>
    #include<set>
    
    #define ll long long
    #define db double
    #define rg register int
    
    using namespace std;
    
    const int mod=1e9+9;
    
    int n,m,c,ans;
    int g[35][35];
    int C[905][905];
    int f[31][31][11];
    
    inline int qr(){
        char ch;
        while((ch=getchar())<'0'||ch>'9');
        int res=ch^48;
        while((ch=getchar())>='0'&&ch<='9')
            res=res*10+(ch^48);
        return res;
    }
    
    int main(){
        //freopen(".in","r",stdin);
        //freopen(".out","w",stdout);
        n=qr(); m=qr(); c=qr();
        for(rg i=0;i<=900;++i)C[i][0]=1;
        for(rg i=1;i<=900;++i)
            for(rg j=1;j<=i;++j)
                C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
        f[0][0][0]=1;
        for(rg k=1;k<=c;++k){
            rg x=qr();
            for(rg i=1;i<=n;++i){
                for(rg j=1;j<=m;++j){
                    g[i][j]=0;
                    if(i*j<x)continue;
                    g[i][j]=C[i*j][x];
                    for(rg l=1;l<=i;++l){
                        for(rg r=1;r<=j;++r){
                            if(l==i&&r==j)continue;
                            g[i][j]-=(ll)g[l][r]*C[i][l]%mod*C[j][r]%mod;
                            if(g[i][j]<mod)g[i][j]+=mod;
                        }
                    }
                }
            }
            for(rg i=1;i<=n;++i){
                for(rg j=1;j<=m;++j){
                    for(rg l=0;l<i;++l){
                        for(rg r=0;r<j;++r){
                            if((i-l)*(j-r)<x)continue;
                            f[i][j][k]+=(ll)f[l][r][k-1]*g[i-l][j-r]%mod*C[n-l][i-l]%mod*C[m-r][j-r]%mod;
                            if(f[i][j][k]>mod)f[i][j][k]-=mod;
                        }
                    }
                }
            }
        }
        for(rg i=1;i<=n;++i)
            for(rg j=1;j<=m;++j)
                (ans+=f[i][j][c])%=mod;
        printf("%d
    ",ans);
        return 0;
    }
    
    
  • 相关阅读:
    我的UI启蒙之路
    关于UI设计行业的认识再到认识
    谈谈我对Ui设计师的一些观点
    Web前端工程师常去的15个技术网站
    Banner中文字怎么排版才好看?
    UI设计师经常去的五个网站
    PS快捷键大全,记住这些就够了!
    UI设计师如何提升审美?
    170. Two Sum III
    169. Majority Element
  • 原文地址:https://www.cnblogs.com/812-xiao-wen/p/10685730.html
Copyright © 2020-2023  润新知