混合揹包

混合揹包就是01 徹底 多重揹包的結合體。c++

那麼咱們把他們拆成兩大部分來枚舉,一是01,二是徹底。spa

而對於多重揹包,咱們能夠n個拆成1+2+4..2^t-1<k(t爲知足關係的最大整數個數)個01揹包。code

代碼blog

#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;
} 
相關文章
相關標籤/搜索