01背包问题,完全背包问题,多重背包问题C++实现

01背包问题,完全背包问题,多重背包问题C++实现


  • 01背包问题:
    有 N 件物品和一个容量为 V 的背包。放入第 i 件物品耗费的费用是 Ci1,得到的
    价值是 Wi。求解将哪些物品装入背包可使价值总和最大。

  • 完全背包问题:
    有 N 种物品和一个容量为 V 的背包,每种物品都有无限件可用。放入第 i 种物品
    的费用是 Ci,价值是 Wi。求解:将哪些物品装入背包,可使这些物品的耗费的费用总
    和不超过背包容量,且价值总和最大。

  • 多重背包问题:
    有 N 种物品和一个容量为 V 的背包。第 i 种物品最多有 Mi 件可用,每件耗费的
    空间是 Ci,价值是 Wi。求解将哪些物品装入背包可使这些物品的耗费的空间总和不超
    过背包容量,且价值总和最大。

基于《背包问题九讲 2.0 beta1.2》实现
参考:动态规划之背包问题系列 - SMON的文章 - 知乎
0-1背包问题的动态规划算法 - Bat特白的文章 - 知乎
非常感谢各位的博客解答,如果大家看完后有不理解的可以参考代码,也可以自己进行实现,这样才能更深刻的理解。
在这里插入图片描述

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
// 01背包问题
int zeroOnePack(int V,vector<int> w,vector<int> c){
    vector<vector<int>> dp(w.size()+1,vector<int>(V+1,0));
    // 使用二维数组
    for(int i=1;i<5+1;++i){
        for(int j=1;j<V+1;++j){
            if(c[i-1] > j){
                dp[i][j] = dp[i-1][j];
            } else{
                dp[i][j] = max(dp[i-1][j],w[i-1]+dp[i-1][j-c[i-1]]);
            }
        }
    }
    return dp[w.size()][V];
}
// 01背包问题优化
void zeroOnePackCore(vector<int> &F,int c,int w,int V){
    for(int v=V;v>=c;v--){
        F[v] = max(F[v],F[v-c] + w);
    }
}
int zeroOnePackOptimize(int V,vector<int> w,vector<int> c){
    // 使用一维数组
    vector<int> dp2(V+1,0);
    for(int i=1;i<w.size()+1;i++){
        zeroOnePackCore(dp2,c[i-1],w[i-1],V);
    }
    return dp2[V];
}


// 完全背包问题
int completePack(int V,vector<int> w,vector<int> c){
    vector<vector<int>> dp(w.size()+1,vector<int>(V+1,0));
    for(int i=1;i<5+1;++i){
        for(int j=1;j<V+1;++j){
            if(c[i-1] > j){
                dp[i][j] = dp[i-1][j];
            } else{
                dp[i][j] = max(dp[i-1][j],w[i-1]+dp[i][j-c[i-1]]);
            }
        }
    }
    return dp[w.size()][V];
}
// 完全背包问题优化
void completePackCore(vector<int> &F,int c,int w,int V){
    for(int v=c;v<=V;v++){
        F[v] = max(F[v],F[v-c] + w);
    }
}
int completePackOptimize(int V,vector<int> w,vector<int> c){
    vector<int> dp(V+1,0);
    for(int i=1;i<w.size()+1;i++)
        completePackCore(dp,c[i-1],w[i-1],V);
    return dp[V];
}

// 多重背包问题
int multiplePack(int V,vector<int> w,vector<int> c,vector<int> M){
    vector<int> dp(V+1,0);
    for(int i=1;i<w.size()+1;i++){
        for(int j=V;j>=c[i-1];j--){
            for(int k=0;k<=min(M[i-1],j/c[i-1]);k++)
                dp[j] = max(dp[j],dp[j-k*c[i-1]]+k*w[i-1]);
        }
    }
    return dp[V];
}
// 多重背包问题优化
void multiplePackCore(vector<int> &F,int c,int w,int m,int V){
    if(c * m >= V){
        completePackCore(F,c,w,V);
        return;
    }
    int k = 1;
    while(k < m){
        zeroOnePackCore(F,c*k,w*k,V);
        m = m - k;
        k = k * 2;
    }
    zeroOnePackCore(F,c*m,w*m,V);
}
int multiplePackOptimize(int V,vector<int> w,vector<int> c,vector<int> M){
    vector<int> dp(V+1,0);
    for(int i=1;i<w.size()+1;i++){
        multiplePackCore(dp,c[i-1],w[i-1],M[i-1],V);
    }
    return dp[V];
}
int main(){
    int N = 5;
    vector<int> w{1,6,18,22,28};    // 价值worth
    vector<int> c{1,2,5,6,7};       // 耗费(重量)cost
    vector<int> M{0,2,1,1,1};       // 多重背包中的数量number

    int V;              // 背包容量Volume
    cin>>V;

    cout<<"01背包问题的答案为:"<<endl;
    cout<<zeroOnePack(V,w,c)<<endl;
    cout<<zeroOnePackOptimize(V,w,c)<<endl;
    cout<<"完全背包问题的答案是:"<<endl;
    cout<<completePack(V,w,c)<<endl;
    cout<<completePackOptimize(V,w,c)<<endl;
    cout<<"多重背包问题的答案是:"<<endl;
    cout<<multiplePack(V,w,c,M)<<endl;
    cout<<multiplePackOptimize(V,w,c,M)<<endl;

    return 0;
}

运行结果:
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值