poj 2844 多重背包
多重背包,二进制转化为01背包后可解
存在性问题
dp【i】【j】=dp【i-1】【j】|dp【i-1】【j-coin【i】】;位运算
#include<iostream> #include<string.h> using namespace std; const int maxn=100005; int bit_mask[30],nn; int coin[maxn],num[101],value[101]; bool dp[maxn]; void change(int ); int main() { int n,m,i,j; bit_mask[0]=1; for(i=1;i<30;i++) bit_mask[i]=bit_mask[i-1]<<1; while(cin>>n>>m&&n+m) { memset(dp,false,sizeof(dp)); for(i=0;i<n;i++) cin>>value[i]; for(i=0;i<n;i++) cin>>num[i]; change(n); int sum=0; for(i=0;i<nn;i++) sum+=coin[i]; if(sum<m) m=sum; dp[0]=true; for(i=0;i<nn;i++) for(j=m;j>=coin[i];j--) dp[j]=dp[j]|dp[j-coin[i]]; sum=0; for(i=1;i<=m;i++) sum+=dp[i]; cout<<sum<<endl; } return 0; } void change(int n) { int i,j; i=nn=0; for(i=0;i<n;i++) { j=0; while(num[i]+1-bit_mask[j+1]>0) coin[nn++]=bit_mask[j++]*value[i]; coin[nn++]=(num[i]-bit_mask[j]+1)*value[i]; } }