zoukankan      html  css  js  c++  java
  • 【BZOJ 3294】 3294: [Cqoi2011]放棋子 (DP+组合数学+容斥原理)

    3294: [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

    Source

    【分析】

      表示一开始看错题ORZ。。以为相同颜色的不能放一起【这样怎么做??

      然后就是其实题目不是这样的、、、

      DP[i][j][k]表示决策到第k种颜色,前k种颜色一共占了i行j列的方案数。

      枚举第k行占的行数和列数,ii,jj,那么dp[i][j][k]=f[i-ii][j-jj][k-1]*B[ii][jj][k]*C[n-(i-ii)][ii]*C[m-(j-jj)][jj]

      其中C是组合数,B[ii][jj][k]表示用ii行jj列填k个东西的方案(注意B数组要满足每一行每一列都有东西,不然好像很容易算重复)

      对于B数组,我一开始用了两种方法求,都不对(超容易算重复smg,然后很内伤)

      最后感觉只有枚举这一种方法是可以求出来的,

      就是递推 B[x][y][z]=C[x*y][k]-sigma(B[i][j][k]*C[x][i]*C[y][j]) (1<=i<=x&&1<=j<=y&&(i!=x||j!=y))

      【这里是容斥吧?

      组合数学没学好所以我这题又做了很久ORZ。。

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 using namespace std;
     7 #define Mod 1000000009
     8 #define Maxn 910
     9 #define LL long long
    10 
    11 LL sm[15],f[40][40][15];
    12 int n,m,c;
    13 
    14 LL C[Maxn][Maxn];
    15 
    16 void get_c()
    17 {
    18     memset(C,0,sizeof(C));
    19     for(int i=0;i<=n*m;i++) C[i][0]=1;
    20     for(int i=1;i<=n*m;i++)
    21      for(int j=1;j<=i;j++) C[i][j]=(C[i-1][j-1]+C[i-1][j])%Mod;
    22 }
    23 
    24 LL B[40][40][15];
    25 LL get_B(int x,int y,int z)
    26 {
    27     if(B[x][y][z]!=-1) return B[x][y][z];
    28     if(x==0&&sm[z]==0) {B[x][y][z]=1;return 1;}
    29     if(sm[z]<x||sm[z]<y||x*y<sm[z]) {B[x][y][z]=0;return 0;}
    30     LL ans=0;
    31     ans=C[x*y][sm[z]];
    32     for(int i=1;i<=x;i++)
    33      for(int j=1;j<=y;j++)
    34      {
    35          if(i==x&&j==y) continue;
    36          // ans++;
    37          LL X=get_B(i,j,z)%Mod,
    38             Y=(C[x][i]*C[y][j])%Mod;
    39          ans=ans-X*Y;ans%=Mod;
    40          ans=(ans+Mod)%Mod;
    41      }
    42     // printf("B[%d][%d][%d]=%d
    ",x,y,z,ans);
    43     /*for(int i=1;i<=z;i++)
    44         ans=(ans+get_B(x-1,y,z-i)*C[y][i])%Mod;
    45     printf("B[%d][%d][%d]=%d
    ",x,y,z,ans);*/
    46     
    47     /*ans=C[n*m][x];ans%=Mod;
    48     ans-=C[(n-1)*m][x]*n;ans%=Mod;
    49     ans-=C[n*(m-1)][x]*m;ans%=Mod;
    50     ans+=C[(n-1)*(m-1)][x]*n*m;ans%=Mod;
    51     ans=(ans+Mod)%Mod;*/
    52     B[x][y][z]=ans;
    53     return ans;
    54 }
    55 
    56 int main()
    57 {
    58     scanf("%d%d%d",&n,&m,&c);
    59     for(int i=1;i<=c;i++) scanf("%d",&sm[i]);
    60     get_c();
    61     memset(f,0,sizeof(f));
    62     memset(B,-1,sizeof(B));
    63     f[0][0][0]=1;
    64     LL ans=0;
    65     for(int i=1;i<=n;i++)
    66      for(int j=1;j<=m;j++)
    67       for(int k=1;k<=c;k++) get_B(i,j,k);
    68     for(int k=1;k<=c;k++)
    69     {
    70         for(int i=1;i<=n;i++)
    71           for(int j=1;j<=m;j++)
    72           {
    73              for(int ii=1;ii<=i;ii++)
    74               for(int jj=1;jj<=j;jj++)
    75               {
    76                   LL X=(C[n-(i-ii)][ii]*C[m-(j-jj)][jj])%Mod,
    77                      Y=(f[i-ii][j-jj][k-1]*B[ii][jj][k])%Mod;
    78                   f[i][j][k]=(f[i][j][k]+X*Y)%Mod;
    79               }
    80                 
    81                 // f[i][j][k]=(f[i][j][k]+(C[n-(i-ii)][ii]*C[m-(j-jj)][jj])%Mod*(f[i-ii][j-jj][k-1]*C[ii*jj][sm[k]])%Mod)%Mod;
    82             if(k==c) ans=(ans+f[i][j][k])%Mod;
    83             // printf("f[%d][%d][%d]=%lld
    ",i,j,k,f[i][j][k]);
    84           }
    85     }
    86     printf("%lld
    ",ans);
    87     return 0;
    88 }
    View Code

    屏蔽掉的是一开始两种错误方法。。

    2017-03-21 08:28:26

  • 相关阅读:
    console.log添加样式及图片
    高效能Windows人士的N个习惯之一:启动篇
    视频播放插件JWPlayer的使用
    使用 Hexo 在 GitHub 上建立博客 · Utopia's Daily Note
    吴裕雄 Bootstrap 前端框架开发——Bootstrap 网格系统实例:嵌套列
    吴裕雄 Bootstrap 前端框架开发——Bootstrap 网格系统实例:偏移列
    吴裕雄 Bootstrap 前端框架开发——Bootstrap 网格系统实例:响应式的列重置
    吴裕雄 Bootstrap 前端框架开发——Bootstrap 网格系统实例:手机、平板电脑、台式电脑
    吴裕雄 Bootstrap 前端框架开发——Bootstrap 网格系统实例:中型和大型设备
    吴裕雄 Bootstrap 前端框架开发——Bootstrap 网格系统实例:堆叠的水平
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6592642.html
Copyright © 2011-2022 走看看