问题
法外狂徒张三是一个探险家,有一次巧合之下进入到一个有宝藏的洞穴里。这个洞穴有很多种宝贝,每个宝贝的重量不一样,但宝贝数量无限。具体来说有:
A 重 2 价值为 2 数量:无限
B 重 3 价值为 4 数量:无限
C 重 4 价值为 4 数量:无限
D 重 4 价值为 5 数量:无限
E 重 1 价值为 3 数量:无限
现在张三就只有一个背包,这个背包承重为10,张三想知道如何装才能带走价值最大的宝藏?
比较完全背包问题和01背包问题的相同与不同:
相同
:背包的重量是有上限的
不同
:01背包的宝贝只有1个,完全背包的宝贝有无数个。
思路:
完全背包从直觉上是最好解决的,只要能找到那个性价比最高的宝贝就能带走最大的价值对不对?
那么如何找到性价比最高的宝贝呢?和01背包一样,放入第n个宝贝时,已经知道前n-1个宝贝放入的最大价值,这时就比较当前宝贝放入还是不放入。用代码来说就是:
if j >= weight[i]:
bag[j] = max(bag[j-weight[i]] + value[i], bag[j])
else:
bag[j] = bag[j]
同01背包问题的解法一样,从第一个物品放入开始,不断的从小到大的去增加背包的容量。当在同样的背包承重下,价值最大的就是性价比最高的。
0.初始化:
1.当装入第一个宝贝,重量为2,价值为2时:
2.当装入第二个宝贝,重量为3,价值为6时:
装入第二个宝贝前提是已经知道装入第一个宝贝的情况,当背包承重为3时,可以装入第二个宝贝就比装入第一个宝贝价值高
max(bag[3-3] + 6, 2) = max(4, 2) = 6
当装入第二个宝贝之后,这时的列表就是考虑放入前两个宝贝时,背包承重各个值下的最大价值
3.当装入第三个宝贝,重量为4,价值为4:
重量为4时,max(bag[4-4]+4,bag[4]) = max(4,6) = 6
,所以,这个宝贝不能放入
当装入第三个宝贝之后,这时的列表就是考虑放入前三个宝贝时,背包承重各个值下的最大价值
4.当装入第四个宝贝,重量为4,价值为5时:
同上,max(bag[4-4]+5,bag[4]) = max(5,6) = 6
当装入第四个宝贝之后,这时的列表就是考虑放入前四个宝贝时,背包承重各个值下的最大价值
5.当装入第五个宝贝,重量为1,价值为3时:
在同等重量下,第五个宝贝的价值比前四个最大值都大,几乎横扫一篇,最后更是能够拿到30这个最大的价值。
当装入第五个宝贝之后,这时的列表就是考虑放入五个宝贝时,背包承重各个值下的最大价值,最大价值就是30
代码
weight = [2,3,4,4,1]
value = [2,6,4,5,3]
weight_most=10
bag = [0 for i in range(weight_most+1)]
for i in range(len(weight)):
for j in range(1, weight_most+1):
if j >= weight[i]:
bag[j] = max(bag[j-weight[i]]+value[i],bag[j])
print(bag)
print(bag[-1])