动态规划——背包问题

背包问题

0-1背包

一共有n件物品,第i(i从1开始)件物品的重量为w[i],价值为v[i]。在总重量不超过背包承载上限W的情况下,能够装入背包的最大价值是多少?

问题描述

假如你要去野营,你有一个容量为6磅的背吧,需要觉得该携带下面的哪些东西。其中每样东西都有相应的价值,价值越大意味着越重要。

  • 水(重3磅,价值10);
  • 书(重1磅,价值3);
  • 食物(重2磅,价值9);
  • 夹克(重2磅,价值5);
  • 相机(重1磅,价值6)。

请问携带哪些东西时价值最高?

解题思路

dp[i][j]表示只看前i个物品,总体积是j的情况下,总价值最大是多少

  • 不选第i个物品:f[i][j]=f[i-1][j]
  • 选第i个物品:f[i][j]=f[i-1][j-v(i)]+w[i],在两者之间选取大值。

初始化,f[0][0]=0,表示什么都没装,价值也为0.
计算得表格:

0 1 2 3 4 5 6
0 0 10 10 10 10
3 3 10 13 13 13
食物 3 9 12 13 19 22
夹克 3 9 12 14 19 22
相机 6 9 15 18 20 25

Python代码:

n, v = map(int,input().split())
goods = []
for i in range(n):
    goods.append([int(i) for i in input().split()])
dp = [[0 for j in range(v+1)] for i in range(n)]
for i in range(n):  # 物品ID
    for j in range(1, v+1):  # 表格中的纵轴,1,2,3,4,5,6
        if goods[i][0]<=j:
            dp[i][j] = max(goods[i][1]+dp[i-1][j-goods[i][0]], dp[i-1][j])
        else:
            dp[i][j] = dp[i-1][j]
print(dp[-1][-1])

输出:

25

优化

根据代码可以看出整个过程都只和上一层有关,和前面的无关,因此可以考虑将dp转化为只有一层的。但这里需要注意的是不能从前往后,会导致dp[j-goods[i][0]]变化,因此要倒序。

n, v = map(int, input().split())
goods = []
for i in range(n):
    goods.append([int(i) for i in input().split()])
dp = [0 for i in range(v+1)]
for i in range(n):
    for j in range(v, -1, -1):
        if goods[i][
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kaili_ya

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值