\(dp[i][j]\) :考虑到前 i 行,有 j 个 2 的方案数。
设有k个1(计算可得)。
-
\(a_{i+1} = 0\):
\(dp[i][j] \to dp[i+1][j]\)
-
\(a_{i+1}=1\):
\(dp[i][j]\times(n-j-k) \to dp[i + 1][j]\)
\(dp[i][j]\times k \to dp[i + 1][j + 1]\)
-
\(a_{i+1}=2\):
\(dp[i][j]\times \tbinom{n-j-k}{2} \to dp[i + 1][j]\)
\(dp[i][j] \times (n - j - k) \times k \to dp[i + 1][j + 1]\)
\(dp[i][j] \times \tbinom{k}{2} \to dp[i + 1][j + 2]\)
\(dp[i][j] \times \tbinom{n-j-k}{1} \to dp[i][j+1]\)
\(\tbinom{n}{m} = \frac{n!}{(n-m)!m!}\)
AcCode:
#include <bits/stdc++.h>
using namespace std;
#define rep(i,l,r) for(int i = (int)l;i <= (int)r;i++)
#define per(i,r,l) for(int i = (int)r;i >= (int)l;i--)
#define pb push_back
#define all(a) a.begin(),a.end()
#define fi first
#define se second
#define mp make_pair
#define SZ(a) (int)(a.size())
#define random(l, r) (rand() * 1ll * rand() % (r - l + 1) + l)
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef long long ll;
typedef double db;
const int N = 1e4 + 10, inf = INT_MAX, P = 998244353;
int n;
int a[N], b[N], sum[N];
ll dp[N], tmp[N], f[N], inv[N];
ll rp(ll a, int b) {
ll res = 1;
for (; b; (a *= a) %= P, b /= 2)
if (b & 1)
(res *= a) %= P;
return res;
}
void init() {
f[0] = 1;
rep(i,1,n) f[i] = f[i - 1] * i % P;
rep(i,0,n) inv[i] = rp(f[i], P - 2);
}
ll C(int a, int b) {
if (a < b) return 0;
return f[a] * inv[a - b] % P * inv[b] % P;
}
int main() {
scanf("%d", &n);
init();
int cnt = 0, t1 = 0, t2 = 0;
rep(i,1,n) {
scanf("%d", &a[i]);
sum[i] = sum[i - 1] + a[i];
t1 += a[i];
}
rep(i,1,n) {
scanf("%d", &b[i]);
cnt += (b[i] == 2);
t2 += b[i];
}
if (t1 != t2) {
puts("0");
return 0;
}
tmp[0] = 1;
rep(i,0,n - 1) {
rep(j,0,n) {
int k = sum[i] - j * 2;// k个1
if (!tmp[j] || k < 0 || n - j - k < 0) continue;
if (a[i + 1] == 0)
(dp[j] += tmp[j]) %= P;
else if (a[i + 1] == 1) {
(dp[j] += tmp[j] * (n - j - k) % P) %= P;
(dp[j + 1] += tmp[j] * k % P) %= P;
} else {
(dp[j] += tmp[j] * C(n - j - k, 2) % P) %= P;
(dp[j + 1] += tmp[j] * (n - j - k) % P * k % P) %= P;
(dp[j + 1] += tmp[j] * C(n - j - k, 1) % P) %= P;
(dp[j + 2] += tmp[j] * C(k, 2) % P) %= P;
}
}
rep(j,0,n) {
tmp[j] = dp[j];
dp[j] = 0;
}
}
int _cnt = sum[n] - cnt * 2;
ll ans = tmp[cnt];
ans = ans * rp(C(n, cnt), P - 2) % P;
ans = ans * rp(C(n - cnt, _cnt), P - 2) % P;
printf("%lld\n", ans);
return 0;
}
标签:tmp,cnt,int,题解,rep,abc273G,dp,define
From: https://www.cnblogs.com/Vancezyx/p/17061450.html