zoukankan      html  css  js  c++  java
  • bzoj1004 [HNOI2008]Cards

    传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1004

    【题解】

    Burnside引理,考虑Polya原理的推导,由于循环节必须染相同的颜色,那么可以dp出方案。

     1 # include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int N = 110;
     5 int A, B, C, m, mod, n;
     6 int p[N][N];
     7 bool vis[N];
     8 int w[N], wn;
     9 int f[N][N][N];
    10 
    11 inline int dp(int id) {
    12     wn = 0;
    13     for (int i=1; i<=n; ++i) vis[i] = 0;
    14     for (int i=1; i<=n; ++i) {
    15         if(vis[i]) continue;
    16         int x = i, t = 0;
    17         while(vis[x] == 0) {
    18             vis[x] = 1; 
    19             x = p[id][x];
    20             ++ t;
    21         }
    22         w[++wn] = t;
    23     }
    24     for (int i=0; i<=A; ++i)
    25         for (int j=0; j<=B; ++j)
    26             for (int k=0; k<=C; ++k) f[i][j][k] = 0;
    27     f[0][0][0] = 1;
    28     for (int cur=1; cur<=wn; ++cur)
    29         for (int i=A; i>=0; --i)
    30             for (int j=B; j>=0; --j)
    31                 for (int k=C; k>=0; --k) {
    32                     if(i >= w[cur]) {
    33                         f[i][j][k] = f[i][j][k] + f[i-w[cur]][j][k];
    34                         if(f[i][j][k] >= mod) f[i][j][k] -= mod;
    35                     }
    36                     if(j >= w[cur]) {
    37                         f[i][j][k] = f[i][j][k] + f[i][j-w[cur]][k];
    38                         if(f[i][j][k] >= mod) f[i][j][k] -= mod;
    39                     }
    40                     if(k >= w[cur]) {
    41                         f[i][j][k] = f[i][j][k] + f[i][j][k-w[cur]];
    42                         if(f[i][j][k] >= mod) f[i][j][k] -= mod;
    43                     }
    44                 }
    45     return f[A][B][C];
    46 }
    47 
    48 inline int pwr(int a, int b) {
    49     int ret = 1;
    50     while(b) {
    51         if(b&1) ret = ret * a % mod;
    52         a = a * a % mod;
    53         b >>= 1;
    54     }
    55     return ret;
    56 }
    57     
    58         
    59 int main() {
    60     cin >> A >> B >> C >> m >> mod;
    61     n = A + B + C;
    62     for (int i=1; i<=m; ++i) 
    63         for (int j=1; j<=n; ++j) cin >> p[i][j];
    64     ++m;
    65     for (int i=1; i<=n; ++i) p[m][i] = i;
    66     int ans = 0;
    67     for (int i=1; i<=m; ++i) {
    68         ans = ans + dp(i);
    69         if(ans >= mod) ans -= mod;
    70     }
    71     ans = ans * pwr(m, mod-2) % mod;
    72     cout << ans << endl;
    73     return 0;
    74 }
    View Code
  • 相关阅读:
    [转]测试的基本概念
    记录
    flash 与 程序通讯
    怎么正确的建立项目
    安装包的制作
    JS
    页面刷新定位
    [转]C#处理XML
    MSN机器人
    报表 的使用
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj1004.html
Copyright © 2011-2022 走看看