大意
给定 n 行, m 列的格子,可以涂黑,求每行每列涂黑不超过 2 个的方案数。
题解
设 f(i,j,k) 为考虑了前 i 行,有 j 列涂黑 1 个, k 列涂黑 2 个的方案数。
有转移:
f(i,j,k)←f(i,j,k)f(i+1,j,k)←f(i,j,k)(1m−j−k)f(i+1,j−1,k+1)←f(i,j,k)(1j)f(i+1,j+2,k)←f(i,j,k)(2m−j−k)f(i+1,j,k+1)←f(i,j,k)(1m−j−k)f(i+1,j−2,k+2)←f(i,j,k)(2j)
代码
提交记录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 110, MOD = 9999973, INV2 = 4999987;
typedef long long ll;
int n, m; ll f[MAXN][MAXN][MAXN];
ll comb(ll x, ll y) { assert(y == 1 || y == 2); if (y == 1) return x; else return x * (x - 1) % MOD * INV2 % MOD; }
signed main() { cin >> n >> m; f[0][0][0] = 1; for (int i = 0; i < n; i++) { for (int j = 0; j <= m; j++) { for (int k = 0; j + k <= m; k++) { f[i + 1][j][k] = (f[i + 1][j][k] + f[i][j][k]) % MOD; if (m - j - k >= 1) f[i + 1][j + 1][k] = (f[i + 1][j + 1][k] + f[i][j][k] * comb(m - j - k, 1) % MOD) % MOD; if (j >= 1) f[i + 1][j - 1][k + 1] = (f[i + 1][j - 1][k + 1] + f[i][j][k] * comb(j, 1)) % MOD; if (m - j - k >= 2) f[i + 1][j + 2][k] = (f[i + 1][j + 2][k] + f[i][j][k] * comb(m - j - k, 2)) % MOD; if (j >= 1 && m - j - k >= 1) f[i + 1][j][k + 1] = (f[i + 1][j][k + 1] + f[i][j][k] * comb(m - j - k, 1) % MOD * comb(j, 1) % MOD) % MOD; if (j >= 2) f[i + 1][j - 2][k + 2] = (f[i + 1][j - 2][k + 2] + f[i][j][k] * comb(j, 2) % MOD) % MOD; } } }
ll res = 0; for (int j = 0; j <= m; j++) for (int k = 0; k + j <= m; k++) res = (res + f[n][j][k]) % MOD;
cout << res << endl; }
|