传送门
思路简介
对于一组可能的小球组合,设数量和为,最大值为,那么能分成的最小组数即为。观察到的值不会大于,我们可以用一个数组记录每一种数量和的出现次数,将数量从小到大排序后一边通过遍历数组分情况来统计答案,一边更新数组即可。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| #include <bits/stdc++.h> #define read std::cin #define write std::cout typedef long long ll;
const int N = 5005; const int mod = 998244353;
int n, a[N]; ll dp[N], res;
int main() { std::ios::sync_with_stdio(false); read.tie(0), write.tie(0); read >> n; for (int i = 1; i <= n; ++i) read >> a[i]; std::sort(a + 1, a + 1 + n); dp[0] = 1ll; for (int i = 1; i <= n; ++i) { for (int j = 5000; j >= a[i] + 1; --j) { res = (res + (j + a[i] + 1) / 2 * dp[j] % mod) % mod; if (j + a[i] <= 5000) dp[j + a[i]] = (dp[j + a[i]] + dp[j]) % mod; } for (int j = a[i]; j >= 0; --j) { res = (res + dp[j] * a[i] % mod) % mod; if (j + a[i] <= 5000) dp[j + a[i]] = (dp[j + a[i]] + dp[j]) % mod; } } write << res; return 0; }
|