恐怖!!!
2026-10-09 22:21:28
发布于:四川
3阅读
0回复
0点赞
#include <bits/stdc++.h>
using namespace std;
const int MOD = 998244353;
const int MAX_A = 5000;
uint16_t cnt[MAX_A + 1]; // 每个长度的出现次数
uint32_t dp[MAX_A + 1]; // 子集和计数
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
memset(cnt, 0, sizeof(cnt));
for (int i = 0; i < n; ++i) {
int x;
cin >> x;
++cnt[x];
}
dp[0] = 1;
long long ans = 0;
int pow2 = 1; // 滚动维护 2^i
int processed = 0; // 已处理木棍数
for (int v = 1; v <= MAX_A; ++v) {
int c = cnt[v];
if (c == 0) continue;
// 依次处理每一根长度为 v 的木棍
for (int k = 0; k < c; ++k) {
// 统计 dp[0..v] 的和
int sum_le = 0;
for (int s = 0; s <= v; ++s) {
sum_le += dp[s];
if (sum_le >= MOD) sum_le -= MOD;
}
int ways = pow2 - sum_le;
if (ways < 0) ways += MOD;
ans += ways;
if (ans >= MOD) ans -= MOD;
// 0/1 背包加入一根长度为 v 的木棍
for (int s = MAX_A; s >= v; --s) {
dp[s] += dp[s - v];
if (dp[s] >= MOD) dp[s] -= MOD;
}
// 更新 2 的幂和已处理计数
pow2 = (pow2 * 2LL) % MOD;
++processed;
}
}
cout << ans << '\n';
return 0;
}
这里空空如也








有帮助,赞一个