多重背包题目描述:
有N种物品,第i种物品的体积是Ci,价值是Wi,每种物品的数量都是有限的,为 Ni。
现在又容量为V的背包,请你放入若干物品,在总体积不超过V的条件下,使得总价值尽可能大。
考虑二进制的思想,将第i种 物品分成若干件物品,可以有(ci,wi),(ci*2,wi*2),(ci*4,wi*4),等等。
每件物品有一个系数,分别为1,2,4,~~~2^(k-1),n-2^k+1,k是满足n-2^k+1>0的最大整数。
n件物品,就拆分成至多1ogn件物品
再转化成01背包问题求解,原问题复杂度降低到O(v{logn)
#include<bits/stdc++.h>
using namespace std;
int v[500],n[10],dp[1000000];
int main()
{
int sum=0;
for(int i=1;i<=6;i++){
scanf("%d",&n[i]);
sum+=n[i]*i;
}
int meng=sum/2;
if(sum%2){
printf("Can't be divided.\n");
}else{
int num=1;
for(int i=1;i<=6;i++){
int k=1,tmp=n[i];
for(k=1;k<=tmp;k<<=1){
v[num++]=i*k;
tmp-=k;
}
if(tmp){
v[num++]=i*tmp;
}
}
for(int i=1;i<=num-1;i++){
for(int j=meng;j>=v[i];j--){
dp[j]=max(dp[j],dp[j-v[i]]+v[i]);
}
}
if(dp[meng]=meng){
printf("Can be divided.\n");
}else{
printf("Can't be divided.\n");
}
}
return 0;
}