zoukankan      html  css  js  c++  java
  • 【CQOI2011】放棋子

    题面

    https://www.luogu.org/problem/P3158

    题解

    首先,对于此题,不同的行列之间应该是独立的(因为每一行每一列只能放一种颜色)

    一些同色棋子对它们所在的行和列是支配的关系。

    设$F[i][j][k]$为考虑了前$i$种颜色,它们支配了$i$行$j$列的方案数。(这里,一开始写的时候,我没有记录第一维,用背包的方式转移,但其实是没有“这个颜色不选”这种选择的,所以最少也要用滚动数组优化一下)

    然后算$g[i][j]$,$k$个点的颜色,恰好支配了$i$行$j$列的方案数,我们先用组合数算最多,然后把没有支配到的去掉就可以了。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define mod 1000000009
    #define LL long long
    #define ri register int
    
    using namespace std;
    
    int c[1000][1000];
    int n,m,yourc,g[15][50][50],f[15][50][50];
    int cnt[255];
    
    int mul(int a,int b) {
      LL c=a*1LL*b;
      return c%mod;
    }
    
    int main(){
      scanf("%d %d %d",&n,&m,&yourc);
      c[0][0]=1;
      for (ri i=1;i<=n*m;i++)
        for (ri j=0;j<=i;j++)
          if (j==0 || j==i) c[i][j]=1; else c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
    
      for (ri i=1;i<=yourc;i++) scanf("%d",&cnt[i]);
      memset(g,0,sizeof(g));
      for (ri ki=1;ki<=yourc;ki++) {
        for (ri i=1;i<=n;i++)
          for (ri j=1;j<=m;j++) {
            if (cnt[ki]>i*j) continue;
            if (cnt[ki]<max(i,j)) continue;
            g[ki][i][j]=c[i*j][cnt[ki]];
            for (ri ii=1;ii<=i;ii++)
              for (ri jj=1;jj<=j;jj++) if (ii!=i || jj!=j) {
                g[ki][i][j]-=mul(mul(c[i][ii],g[ki][ii][jj]),c[j][jj]);
                g[ki][i][j]+=mod;
                g[ki][i][j]%=mod;
              }
          }
      }
      f[0][0][0]=1;
      for (ri k=1;k<=yourc;k++)
        for (ri i=n;i>=1;i--)
          for (ri j=m;j>=1;j--)
            for (ri ii=1;ii<=i;ii++)
              for (ri jj=1;jj<=j;jj++) {
                if (g[k][ii][jj]) {
                  f[k][i][j]+=mul(mul(mul(f[k-1][i-ii][j-jj],c[n-(i-ii)][ii]),c[m-(j-jj)][jj]),g[k][ii][jj]);
                  f[k][i][j]%=mod;
                }
              }
      LL ans=0;
      for (ri i=1;i<=n;i++)
        for (ri j=1;j<=m;j++) ans+=f[yourc][i][j],ans%=mod;
      cout<<ans<<endl;
    }
  • 相关阅读:
    JavaScript:综合案例---房贷计算器的实现
    iOS:如何将自己的SDK用CocoaPods管理
    JavaScript:综合案例-表单验证
    JavaScript:日期选择器组件的使用
    JavaScript : 基本的处理事件
    JavaScript:window窗口对象
    JavaScript:文本域事件处理
    JavaScript:下拉列表框的事件处理
    JavaScript:复选框事件的处理
    JavaScript:单选钮的事件处理
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11478675.html
Copyright © 2011-2022 走看看