混合背包

混合背包就是01 完全 多重背包的结合体。

那么我们把他们拆成两大部分来枚举,一是01,二是完全。

而对于多重背包,我们可以n个拆成1+2+4..2^t-1<k(t为满足关系的最大整数个数)个01背包。

代码

#include<bits/stdc++.h>
#define maxn 1010000
using namespace std;
long long v[maxn],w[maxn],k[maxn];//价值,重量,种类 
int n,T;
int size;
int t=1;
long long dp[maxn];
int main(){
    cin>>n>>T;
    int vv,ww,kk;//价值,重量 
    for(int i=1;i<=n;i++){
        cin>>ww>>vv>>kk;
        if(kk==-1){//01背包 
            v[++size]=vv;
            w[size]=ww;
            k[size]=1;
        }
        else if(kk==0){//完全背包 
            v[++size]=vv;
            w[size]=ww;
            k[size]=0;
        }
        else if(kk>=1){//多重背包拆解为01背包 
            t=1;
            while(t<=kk){
                v[++size]=vv*t;
                w[size]=ww*t;
                k[size]=1;
                kk=kk-t;
                  t <<= 1;
            }
                v[++size]=vv*kk;
                w[size]=ww*kk;
                k[size]=1;
        }
    }
    /*for(int i=1;i<=size;i++){
        cout<<w[i]<<" ";//体积 
    }*/ 
    dp[0]=0;
    for(int i=1;i<=size;i++){
        if(k[i]==1){
            for(int j=T;j>=w[i];j--){
                dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
            }
        }
        else if(k[i]==0){
            for(int j=w[i];j<=T;j++){
                dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
            }
        }
    }
    cout<<dp[T]<<endl;
    return 0;
} 

 

posted @ 2019-10-31 00:14  毛炯人  阅读(301)  评论(0编辑  收藏  举报