首页 > 其他 > 详细

混合背包

时间:2019-10-31 01:13:30      阅读:96      评论:0      收藏:0      [点我收藏+]

混合背包就是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;
} 

 

混合背包

原文:https://www.cnblogs.com/china-mjr/p/11768929.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!