CodeForces 489F DP Special Matrices

首先统计一下前m行中,有x列1的个数为0,有y列1的个数为1.

设d(i, j)表示有i列1的个数为0,有j列1的个数为1,能到达这个状态的矩阵的个数。

则d(x, y) = 1

每一行都是两个1一起放,枚举这两个1分别放在了哪种列上面

于是有状态转移:

  • d(i - 2, j + 2) += d(i, j) * C(i, 2)
  • d(i - 1, j) += d(i, j) * i * j
  • d(i, j - 2) += d(i, j) * C(j, 2)
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int maxn = 500 + 10;
 8 
 9 int n, m;
10 
11 long long d[maxn][maxn], MOD;
12 
13 char s[maxn];
14 int cnt[maxn];
15 
16 int main()
17 {
18     scanf("%d%d%I64d", &n, &m, &MOD);
19     for(int i = 0; i < m; i++)
20     {
21         scanf("%s", s);
22         for(int j = 0; j < n; j++) if(s[j] == '1') cnt[j]++;
23     }
24 
25     int zero = 0, ones = 0;
26     for(int i = 0; i < n; i++) if(!cnt[i]) zero++; else if(cnt[i] == 1) ones++;
27 
28     d[zero][ones] = 1;
29     for(int i = n; i >= 0; i--)
30         for(int j = n; j >= 0; j--)
31         {
32             if(i >= 2) d[i-2][j+2] = (d[i-2][j+2] + d[i][j] * i * (i - 1) / 2) % MOD;
33             if(i && j) d[i-1][j] = (d[i-1][j] + d[i][j] * i * j) % MOD;
34             if(j >= 2) d[i][j-2] = (d[i][j-2] + d[i][j] * j * (j - 1) / 2) % MOD;
35         }
36 
37     printf("%I64d
", d[0][0]);
38 
39     return 0;
40 }
代码君
原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4720305.html