题解:AT_mujin_pc_2018_f チーム分け
zhangxiaoyu008 · · 题解
神秘题目被神秘搬题人搬到 NOIP 模拟赛 T1。(所以模拟赛成了全原题模拟赛,难度:紫紫紫紫)
以为是签到题,做了 1h 30min 还是只会枚举。
可以考虑设计状态
令
转移:考虑枚举
注:转移可以化简为
:::info[
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e3 + 10, mod = 998244353;
int n, x, cnt[N], f[N][N], fact[N], infact[N];
int qmi(int a, int k) {
int res = 1;
while(k) {
if(k & 1) res = (LL)res * a % mod;
a = (LL)a * a % mod;
k >>= 1;
}
return res;
}
int main()
{
scanf("%d", &n);
fact[0] = infact[0] = 1;
for(int i = 1; i <= n; i ++) {
fact[i] = (LL)fact[i - 1] * i % mod;
infact[i] = qmi(fact[i], mod - 2);
}
for(int i = 0; i < n; i ++) {
scanf("%d", &x);
cnt[x] ++;
}
f[n][0] = 1;
for(int i = n; i; i --)
for(int j = 0; j <= n; j ++)
if(f[i][j]) {
int v = j + cnt[i];
int inv = (LL)f[i][j] * fact[v] % mod;
for(int k = 0, t = 0; t <= v; k ++, t += i) {
f[i - 1][v - t] = (f[i - 1][v - t] + (LL)inv * infact[k] % mod * infact[v - t] % mod) % mod;
inv = (LL)inv * infact[i] % mod;
}
}
printf("%d\n", f[0][0]);
return 0;
}