題目連結:https://atcoder.jp/contests/abc321/tasks/abc321_f
題目大意:
給定大小為 \(k\) 的揹包和 \(q\) 次操作,支援兩種操作:
- 插入一個大小為 \(x\) 的元素;
- 刪除一個大小為 \(x\) 的元素。
每次操作後,求裝滿揹包方案數。
解題思路:
可撤銷揹包。
- 插入 \(x\) 時,for i = K -> x 執行
f[i] += f[i-x]
- 刪除 \(x\) 時,for i = x -> K 執行
f[i] -= f[i-x]
(雖然我程式碼裡是用 V
表示揹包容量的)
示例程式:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 5050;
const long long mod = 998244353;
int q, V, x;
char op[2];
long long f[maxn] = { 1 };
int main() {
scanf("%d%d", &q, &V);
while (q--) {
scanf("%s%d", op, &x);
if (op[0] == '+') {
for (int i = V; i >= x; i--)
f[i] = (f[i] + f[i-x]) % mod;
}
else {
for (int i = x; i <= V; i++)
f[i] = (f[i] - f[i-x] + mod) % mod;
}
printf("%lld\n", f[V]);
}
return 0;
}
雙倍經驗:洛谷P4141 消失之物
參考資料:可撤銷揹包學習筆記 作者:Nicrobot