01背包、完全背包、多重背包

一、01背包问题
问题描述:给定n个重量为w1,w2,……,wn;价值为v1,v2,……,vn的物品和一个能承重为W的背包。求背包能装入的最终价值最多的物品编号。
设F(I,j)为能够放进承重为j的背包的前i个物品中最有价值的子集的总价值。因此:
(1)不包括第i个物品的子集中,最优子集的价值是F(i-1,j)
(2)在包括第i个物品的子集中,最优子集总价值为vi+F(i-1,j-wi)
因此可推导出这个递推式:

F(I,j)=F(I-1,j),j-wi<0
Max{F(I-1,j),vi+F(I-1,j-wi)},j-wi>=0

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;

const int N=4; //物品件数
const int W=5; //背包容量

int main()
{
    int value[N+1]={0,12,10,20,15}; //物品价值
    int weight[N+1] = {0,2,1,3,2};  //物品质量
    int f[N+1][W+1] = {0}; // f[i][j]表示在背包容量为j的情况下, 前i件宝贝的最大价值

    for(int i = 1; i <= N; i++){
        for(int j = 1; j <= W; j++){
            if(j < weight[i])
                f[i][j] = f[i - 1][j];
            else
                f[i][j]=max(f[i-1][j],f[i-1][j-weight[i]]+value[i]);
        }
    }

    for(int i=1;i<=N;i++){
        for(int j=1;j<=W;j++)
            cout<<f[i][j]<<" ";
        cout<<endl;
    }

    return 0;
}

参考链接

二、完全背包
每种物品无限量

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;

const int N=4; //物品件数
const int W=5; //背包容量

int main()
{
    int value[N+1]={0,12,10,20,15}; //物品价值
    int weight[N+1] = {0,2,1,3,2};  //物品质量
    int f[W+1] = {0};

    for(int i = 1; i <= N; i++){
        for(int j = weight[i]; j<=W; j++){
            f[j]=max(f[j],f[j-weight[i]]+value[i]);
        }
    }

    cout<<f[W]<<endl;

    return 0;
}

三、多重背包问题
背包容量为10,5种物品,每种物品的数量为1,2,1,2,1;重量为5,4,3,2,1;价值为1,2,3,4,5。

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;

const int N=5; //物品件数
const int W=10; //背包容量

int main()
{
    int value[N+1]={0,1,2,3,4,5}; //物品价值
    int weight[N+1] = {0,5,4,3,2,1};  //物品质量
    int number[N+1]={0,1,2,1,2,1}; //没件物品的数量
    int f[W+1] = {0};

    for(int i = 1; i <= N; i++){
        for(int k=1;k<=number[i];k++){
            for(int j = W; j>= weight[i]; j--){
                f[j]=max(f[j],f[j-weight[i]]+value[i]);
            }
        }
    }

    cout<<f[W]<<endl;

    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值