zoukankan      html  css  js  c++  java
  • [CQOI2011]放棋子

    题意

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


    思考

    设$f_{i,j,k}$为用前k种棋子,在满足条件的情况下,在i*j的棋盘上每行每列都至少有一枚棋子的总方案数。转移为:

    $f_{i,j,k}=sum_{i_1 leq i}sum{j_1 leq j}{{f_{i-i_1,j-j_1,k-1}*g_{i_1,j_1,a_k}*C(i,i_1)*C(j,j_1)}}$

    其中g的含义为正在i*j的棋盘上放k个同色的棋子,每行每列都至少有一枚棋子的总方案数。考虑g的容斥,转移为:

    $g_{i,j,k}=C(i*j,k)-sum_{i_1 leq i}sum_{j_1 leq j}{{g_{i_1,j_1,}*C(i,i_1)*C(j,j_1)}}(i_1!=i  or  j_1!=j)$

    时间复杂度为$O(n^5*k)$。


    代码

     1 // luogu-judger-enable-o2
     2 #include<bits/stdc++.h>
     3 #define mod 1000000009
     4 using namespace std;
     5 typedef long long int ll;
     6 int n,m,c,a[55];
     7 ll ans,C[1005][1005],g[35][35][1005],f[35][35][15];
     8 void init()
     9 {
    10     C[0][0]=1;
    11     for(int i=1;i<=1000;++i)
    12     {
    13         C[i][0]=1;
    14         for(int j=1;j<=i;++j)
    15             C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
    16     }
    17     for(int i=1;i<30;++i)
    18         g[0][i][0]=g[i][0][0]=1;
    19     for(int i=1;i<=n;++i)
    20         for(int j=1;j<=m;++j)
    21             for(int k=1;k<=i*j;++k)
    22             {
    23                 ll sum=0;
    24                 for(int i1=1;i1<=i;++i1)
    25                     for(int j1=1;j1<=j;++j1)
    26                         if(i1*j1>=k&&(i1!=i||j1!=j))
    27                             sum=(sum+g[i1][j1][k]*C[i][i1]%mod*C[j][j1]%mod)%mod;
    28                 g[i][j][k]=(C[i*j][k]-sum+mod)%mod;
    29             }
    30 }
    31 int main()
    32 {
    33     ios::sync_with_stdio(false);
    34     cin>>n>>m>>c;
    35     for(int i=1;i<=c;++i)
    36         cin>>a[i];
    37     init();
    38     f[0][0][0]=1;
    39     for(int i=1;i<=n;++i)
    40         for(int j=1;j<=m;++j)
    41             for(int k=1;k<=c;++k)
    42                 for(int i1=0;i1<=i;++i1)
    43                     for(int j1=0;j1<=j;++j1)
    44                         f[i][j][k]=(f[i][j][k]+f[i1][j1][k-1]*g[i-i1][j-j1][a[k]]%mod*C[i][i1]%mod*C[j][j1]%mod)%mod;
    45     for(int i=1;i<=n;++i)
    46         for(int j=1;j<=m;++j)
    47             ans=(ans+f[i][j][c]*C[n][i]%mod*C[m][j]%mod)%mod;
    48     cout<<ans<<endl;
    49     return 0;
    50 }
    View Code
  • 相关阅读:
    Hashtable源码分析
    ConcurrentHashMap1.7源码分析
    JDK1.8新特性
    回炉Spring--Bean生命周期及AOP
    @DateTimeFormat 和 @JsonFormat 注解
    面向切面编程-日志切面应用及MDC使用
    maven 多模块开发
    maven 安装
    ztree树节点重叠问题
    Java问题解读系列之IO相关---Java深拷贝和浅拷贝
  • 原文地址:https://www.cnblogs.com/GreenDuck/p/11409330.html
Copyright © 2011-2022 走看看