宁波多校(二) G. 01背包问题(可逆背包)

对于01背包来说,因为每个物品先用和后用是没有区别的

因此满足交换律,对于增加一个w,他多出的方案数就是i-w转移而来

对于减少一个w,某个位置i(i>=w)他在没有w之前的方案就是从i-w且f[i-w]处也没有使用的位置转移而来

因此使用从头往后的完全背包的递推方式可以减去

#include<iostream>
#include<queue>
#include<map>
#include<vector>
#include<cstdio>
#include<algorithm>
#include<stack>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=2e5+10;
const int mod=1e9+7;
int f[N];
int main(){
    int n;
    while(cin>>n){
        int i;
        memset(f,0,sizeof f);
        f[0]=1;
        int ans=0;
        for(i=1;i<=n;i++){
            int type,x;
            cin>>type>>x;
            if(type==1){
                int j;
                for(j=1000;j>=x;j--)
                    f[j]=(f[j]+f[j-x])%mod;
            }
            else{
                for(int j=x;j<=1000;j++)
                    f[j]=(f[j]-f[j-x]+mod)%mod;
            }
            for(int j=0;j<=1000;j++)
                ans^=f[j];
        }
        cout<<ans<<endl;
    }
}
View Code
原文地址:https://www.cnblogs.com/ctyakwf/p/13259589.html