社区讨论

求调代码

P7961[NOIP2021] 数列参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@m28eryyy
此快照首次捕获于
2024/10/14 10:42
去年
此快照最后确认于
2025/11/04 17:13
4 个月前
查看原帖
rt。
CPP
#include <bits/stdc++.h>
#define int long long
int max(int x, int y) { return x > y ? x : y; }
int min(int x, int y) { return x < y ? x : y; }

const int mod = 998244353; 

int pcnt(int x) {
	int ret = 0;
	while (x > 0) ret += x & 1, x >>= 1;
	return ret; 
}

const int M = 1e2 + 10, N = 40; 
int n, m, K, v[M];


int C[N][N]; 
void init() {
	for (int i = 0; i <= n; ++ i) C[i][0] = 1; 
	for (int i = 1; i <= n; ++ i)
		for (int j = 0; j <= i; ++ j) (C[i][j] += (C[i - 1][j - 1] + C[i][j - 1]) % mod) %= mod;
//	for (int i = 0; i <= n; ++ i) {
//		for (int j = 0; j <= i; ++ j) std::cout << C[i][j] << " ";
//		std::cout << "\n"; 
//	}
	return void(); 
}

int dp[M][N][N][N]; 

signed main() {

//	freopen(".in", "r", stdin);
//	freopen(".out", "w", stdout);

	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout.tie(nullptr);

//	dp[i][j][k][l] 表示从第 2^0 位到第 2^(i - 1) 位,共定了 j 个 a,目前共有 k 位为 1,并且对于第 i + 1 位,需要进 l 位的贡献总数
	
	std::cin >> n >> m >> K;
	for (int i = 0; i <= m; ++ i) std::cin >> v[i]; // 每一位对应的贡献
	init(); 
//	刷表法
	for (int j = 0; j <= n; ++ j) dp[0][j][j & 1][j >> 1] = C[n][j];
	for (int i = 0; i < m; ++ i) // 当前已经填好了 2^i 的位,考虑利用其填充 2^(i + 1) 位
		for (int j = 0; j <= n; ++ j) // 第 2^0 ~ 2^i 位 已经选定了 j 个 1,还剩下 n - j 个 1 可选
			for (int k = 0; k <= j; ++ k) // 2^0 ~ 2^i 位,不考虑进位,共计 k 个 1
				for (int l = 0; l <= j; ++ l) // 对于第 2^(i + 1) 位,一共进位了 l * 2^i
					for (int h = 0, _ = n - j; h <= _; ++ h) { // 2^(i + 1) 自己选(不靠进位)的位数
						int now = h + (l >> 1);
						int nowl = now >> 1; // 第 2^i 的进位
						now &= 1; // 第 2^i 的值 01
						int add = C[n - j][h] * v[i + 1] % mod; // 对于 2^i 的贡献
						(dp[i + 1][j + h][now + k][nowl] += dp[i][j][k][l] * add % mod) %= mod;
					}
	int ans = 0;
//	dp[m][n][k][l] | popcount(l / 2) + k <= K
	for (int k = 0; k <= n; ++ k)
		for (int l = 0; l <= n; ++ l) 
			if (pcnt(l >> 1) + k <= K) (ans += dp[m][n][k][l]) %= mod;
	std::cout << ans << "\n"; 
			

	return 0;
	
}

回复

1 条回复,欢迎继续交流。

正在加载回复...