社区讨论

求条玄关

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 条回复,欢迎继续交流。

正在加载回复...