01背包问题

01背包问题是所有背包问题的基础,只有学好01背包,才能掌握背包问题。

01背包:“01”表示只能取或者不取,下面看例题:

【题目描述】
一个旅行者有一个最多能装 M 公斤的背包,现在有 n 件物品,它们的重量分别是W1,W2,...,Wn,它们的价值分别为C1,C2,...,Cn,求旅行者能获得最大总价值。

【输入】
第一行:两个整数,M(背包容量,M<=200)和N(物品数量,N<=30);

第2..N+1行:每行二个整数Wi,Ci,表示每个物品的重量和价值。

【输出】
仅一行,一个数,表示最大总价值。

【输入样例】
10 4
2 1
3 3
4 5
7 9
【输出样例】
12
好了,这是一个经典的01背包问题

做01背包问题只要记住一个公式:

d[j]=max(d[j],d[j-w[i]]+c[i]);
其中 d 数组表示当前容量可以装的最大价值,w[i] 是重量,c[i] 是价值。 

在公式中,我们在装和不装中选一种:

1、不装:就是当前的最大重量 d[j]

2、装:先在当前容量 j 中给 当前重量 w[i] 预留一个位置 (d[j-w[i]]),然后在加上当前价值 c[i]

最后,用max函数在它们当中选大的那个就可以了

公式中有 i 有 j ,那么这是一个双重循环。

完整的c++代码如下:

#include <iostream>
using namespace std;
int v,n,d[2000],c[50],w[50];     //d数组的下标表示容量
int main()
{
    cin >>v >>n;      //v表示容量,n表示数量 
    for (int i=1;i<=n;i++)
        cin >>w[i] >>c[i];
    for (int i=1;i<=n;i++) 
        for (int j=v;j>=w[i];j--)
            //01背包中,第二重循环要倒序,从v到w[i],倒序的原因,切勿刨根问底!
        {
            d[j]=max(d[j],d[j-w[i]]+c[i]);  //公式 
        }
    cout <<d[v]; //注意不是d[n] 
    return 0;
}
这些东西只要背下来就行了,非常简单。

对于第二重循环要倒序的原因:切勿刨根问底!
————————————————
版权声明:本文为CSDN博主「小天狼星_布莱克」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/DUXS11/article/details/125897100

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值