多重背包:平分娃娃(dp)

多重背包题目描述:

有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;
}

猜你喜欢

转载自blog.csdn.net/zhouzi2018/article/details/81087269