CodeForces 489F Special Matrices, codeforces489f
Question:
N (500) * n matrices each row has only two columns. Now we have given several valid matrices for the first m row.
Ideas:
You only need to consider how many columns have 1 and then scan by row. Each maintenance row has only 2 1 in order to construct a valid matrix.
Therefore, we define dp [I] [j] [k] to indicate that column j in row I is scanned to contain 1 column and column k in column I is scanned to contain 2 columns and 1 at this moment 500 ^ 3. the array cannot be opened, so the scrolling I
For dp [I] [j] [k]
If n-j-k> = 2, you can select one of the two columns to transfer to dp [I + 1] [j + 2] [k].
If n-j-k> = 1 & j> = 1, you can change the column of a 1 to 2 and change the column of 0 to 1, that is, transfer it to dp [I + 1] [j] [k + 1]
If j> = 2 then you can select two 1 to 2 that is transferred to dp [I + 1] [J-2] [k + 2]
Code:
#include<cstdio>#include<iostream>#include<cstring>#include<string>#include<algorithm>#include<map>#include<set>#include<vector>#include<queue>#include<cstdlib>#include<ctime>#include<cmath>#include<bitset>using namespace std;typedef long long LL;#define N 510int n, m, mod;int dp[2][N][N];int num[N];char s[N];void add(int &x, int y) {x += y;if (x >= mod)x -= mod;}int main() {scanf("%d%d%d", &n, &m, &mod);for (int i = 1; i <= m; i++) {scanf("%s", s + 1);for (int j = 1; j <= n; j++) {if (s[j] == '1')num[j]++;}}int j = 0, k = 0;for (int i = 1; i <= n; i++) {if (num[i] == 1)j++;else if (num[i] == 2)k++;}dp[m & 1][j][k] = 1;for (int i = m + 1; i <= n; i++) {memset(dp[i & 1], 0, sizeof(dp[i & 1]));for (j = 0; j <= n; j++) {for (k = 0; k + j <= n; k++) {if (dp[(i & 1) ^ 1][j][k]) {int zero = n - j - k, one = j, two = k;LL key = dp[(i & 1) ^ 1][j][k];if (zero >= 2)add(dp[i & 1][one + 2][two],(LL) (zero) * (zero - 1) / 2 % mod * key % mod);if (zero >= 1 && one >= 1)add(dp[i & 1][one][two + 1],key * zero % mod * one % mod);if (one >= 2)add(dp[i & 1][one - 2][two + 2],(LL) (one) * (one - 1) / 2 % mod * key % mod);}}}}printf("%d\n", dp[n & 1][0][n]);return 0;}