hdu多校1C题
题意:有n个物品,体积为v,价值为w,背包容量为m,求恰好能使背包装满的最大物品价值异或和
思路:
状态:f[i][j][k]表示前i个物品能否组成异或和为j,体积恰好为k
状态转移:f[i][j][k]=f[i-1][j^v[i]][k-w[i]]||f[i-1][j][k]
解释:不取第i个物品:f[i-1][j][k],取第i个物品:f[i-1][j^v[i]][j-w[i]]
时间复杂度:1024*1024*1024,必超时
优化:用bitset状压,那么可以批量处理k维
#include <cstdio>
#include <cstring>
#include<iostream>
#include <algorithm>
#include<cmath>
#include<bitset>
using namespace std;
const int N=1100,M=N*N;
bitset<1030> f[1030],g[1030]; //前i个物品,体积是k,异或和是j
int v[N],w[N];
signed main(){
int t;
cin>>t;
while(t--){
memset(f,0,sizeof f);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>v[i]>>w[i];
f[0][0]=1;
for(int i=1;i<=n;i++){
for(int j=0;j<1024;j++)g[j]=f[j],g[j]<<=v[i];
for(int j=0;j<=1024;j++)f[j]|=g[j^w[i]];
}
int flag=1,ans=-1;
for(int i=0;i<1024;i++){
if(f[i][m]==1){
ans=i;
}
}
cout<<ans<<endl;
}
}