Official
F - #(subset sum = K) with Add and Erase Editorial by en_translator
If this problem only has operations of type \(1\) (addition), one can perform a DP (Dynamic Programming) where \(dp\) [ partial sum ] \(=\) { count }. We will try to extend this method to support deletion too.
On addition, the transition of the DP is as follows:
- for each \(i=K,K-1,\dots,x+1,x\) in this order,
- add \(dp[i-x]\) to \(dp[i]\).
Its inverse operation is the correct transition of DP on removal:
- for each \(i=x,x+1,\dots,K-1,K\) in this order,
- subtract \(dp[i-x]\) from \(dp[i-x]\).
Note that one has to store \(dp\) only for the indices \(0,1,\dots,K\). (The value \(dp[K+1]\) and later does not affect to \(dp[K]\) and prior.)
Sample code (C++):
#include<bits/stdc++.h>
#define mod 998244353
using namespace std;
int dp[5005]={0};
int main(){
int q,k;
cin >> q >> k;
dp[0]=1;
while(q>0){
q--;
string s;
int x;
cin >> s >> x;
if(s=="+"){
for(int i=k;i>=x;i--){
dp[i]+=dp[i-x];
dp[i]%=mod;
}
}
else{
for(int i=x;i<=k;i++){
dp[i]+=(mod-dp[i-x]);
dp[i]%=mod;
}
}
cout << dp[k] << "\n";
}
return 0;
}
posted:
last update: