社区讨论
求条玄关
P14364[CSP-S 2025] 员工招聘参与者 4已保存回复 14
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 14 条
- 当前快照
- 1 份
- 快照标识符
- @mi3yjgiw
- 此快照首次捕获于
- 2025/11/18 10:31 3 个月前
- 此快照最后确认于
- 2025/11/18 10:34 3 个月前
自认为马蜂优良,样例过不了
CPP#include <bits/stdc++.h>
#define int long long
using namespace std;
namespace zcq_qwq {
const int N = 500 + 5, mod = 998244353;
int n, m;
string s;
int a[N], f[2][N][N], fact[N], inv[N], t[N], sum[N];
int qpow(int a, int b) {
if (b == 0) return 1ll;
if (b == 1) return a % mod;
int ans = qpow(a, b >> 1ll);
ans = ans * ans % mod;
if (b & 1ll) {
ans = (ans * (a % mod)) % mod;
}
return ans;
}
int c(int x, int y) {
if (y == 0) return 1ll;
if (x == 0) return 0ll;
int fz = fact[x] * inv[x - y] % mod;
int fm = inv[y];
return fz * fm % mod;
}
void main() {
cin >> n >> m;
cin >> s;
s = " " + s;
for (int i = 1; i <= n; i++) {
cin >> a[i];
t[a[i]]++;
}
sum[0] = t[0];
for (int i = 1; i <= 500; i++) {
sum[i] = sum[i - 1] + t[i];
}
fact[0] = 1;
for (int i = 1; i <= 500; i++) {
fact[i] = fact[i - 1] * i % mod;
}
inv[500] = qpow(fact[500], mod - 2);
for (int i = 500; i >= 1; i--) {
inv[i - 1] = inv[i] * i % mod;
}
// cout << c(3, 2) << endl;
f[0][0][0] = 1;
for (int i = 1; i < n; i++) {
memset(f[i & 1], 0, sizeof f[i & 1]);
for (int j = 0; j <= i; j++) {
for (int k = 0; k <= i; k++) {
if (s[i + 1] == '1') {
for (int o = 0; o <= min(t[j + 1], k); o++) {
if (i - o < sum[j]) f[i + 1 & 1][j + 1][k - o] = (f[i + 1 & 1][j + 1][k - o] + c(k, o) * c(t[j + 1], o) % mod * fact[o] % mod *
(sum[j] - (i - k)) % mod * f[i & 1][j][k] % mod) % mod;
}
f[i + 1 & 1][j][k + 1] = (f[i + 1 & 1][j][k + 1] + f[i & 1][j][k]) % mod;
} else {
for (int o = 0; o <= min(k, t[j + 1]); o++) {
if (i - k + o < sum[j + 1]) f[i + 1 & 1][j + 1][k - o] = (f[i + 1 & 1][j + 1][k - o] + c(k, o) * c(t[j + 1], o) % mod * fact[o] % mod *
(sum[j + 1] - (i - k) - o) % mod * f[i & 1][j][k] % mod) % mod;
f[i + 1 & 1][j + 1][k + 1 - o] = (f[i + 1 & 1][j + 1][k + 1 - o] + c(k, o) * c(t[j + 1], o) % mod
* fact[o] % mod * f[i & 1][j][k] % mod) % mod;
}
}
}
}
}
int ans = 0;
for (int i = 0; i <= n - m; i++) {
ans = (ans + f[n & 1][i][n - sum[i]] * fact[n - sum[i]] % mod) % mod;
}
cout << ans;
}
}
signed main() {
// freopen("employ.in", "r", stdin);
// freopen("employ.out", "w", stdout);
zcq_qwq::main();
return 0;
}
/*
f[i][j][k] : 第 i 个位置、有 j 个人被拒绝,k 个人 ci > j;
*/
回复
共 14 条回复,欢迎继续交流。
正在加载回复...