每日一题33. 简单瞎搞题 (滚动数组 + bitset 优化DP)
Posted tags: 篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每日一题33. 简单瞎搞题 (滚动数组 + bitset 优化DP)相关的知识,希望对你有一定的参考价值。 补题链接:Here 这个问题的难点在于如何统计出所有和可能出现的情况,并且不能重复。 不妨令 \\(dp[i][j]\\) 表示为第 \\(i\\) 次选择时,和为 \\(j\\) 的情况是否出现过 但是内存方面需要 \\(1e8\\) 的 \\(int\\) 内存,显然是不可接受的 那么我们考虑用 \\(bitset\\) 优化内存,由递推方程:\\(dp_i = dp_{i}|=(dp_{i-1}<<(j*j))\\) 代表第 \\(i\\) 次选择的时候是否能从当前状态转移到和为\\(j\\) 的状态 写完状态转移方程发现 \\(dp_i\\) 仅与 \\(dp_{i - 1}\\) 有关系,所以由滚动数组来节省空间 以上是关于每日一题33. 简单瞎搞题 (滚动数组 + bitset 优化DP)的主要内容,如果未能解决你的问题,请参考以下文章
很容易想到用桶去存储每一个数,即某个和能够组合出来则为1,否则为0const int N = 110;
bitset<1000010>dp[N];
void solve() {
int n; cin >> n;
dp[0] = 1;
for (int i = 1, l, r; i <= n; ++i) {
cin >> l >> r;
for (int j = l; j <= r; ++j)dp[i] |= (dp[i - 1] << (j * j));
}
cout << dp[n].count() << "\\n";
}
bitset<1000010> now, nxt;
void solve() {
int n; cin >> n;
now[0] = 1;
for (int i = 1, l, r; i <= n; ++i) {
cin >> l >> r;
for (int j = l; j <= r; ++j)
if (j == l)nxt = (now << (j * j));
else nxt |= (now << (j * j));
now = nxt;
}
cout << now.count() << "\\n";
}