完全背包问题

相比于01背包问题
只是单纯的多了一个条件:物品可以重复利用。

这是01背包问题的状态转移方程:

  • 当W-wi大于0时,F(n,w) = max(F(n-1,W-wi)+vi,F(n-1,w))
  • 当W-wi小于0时,F(n,w) = F(n-1,w))

我们只关注第一个方程,对于完全背包问题,当我们用了第n个物品以后,因为n还可以再次被用,因此其中一个最优子结构F(n-1,W-wi)+vi应该变为F(n,W-wi)+vi,代表用来第n个物品以后,还可以用第n个物品。

对应到代码上,F(n-1,W-wi)代表的是对应的是第 n-1 行的物品中的第W-wi个重量的最大值。对应到代码中就是res_pre中的index为W-wi的值。而F(n,W-wi)对应的就是第n行的物品,就应该是res中的index为W-wi的值
,因此,在01背包问题的代码的基础上,只需要把状态转移方程中的res_pre[w - w_list[n]] + v_list[n]改为res[w - w_list[n]] + v_list[n]即可。

代码实现:

N = 4
W = 10
# v_list = [10,40,30,50]
# w_list = [5,4,6,3]
v_list = [1,5,2,4]
w_list = [2,3,5,7]

#用 一维数组保存中间数据。初始化当只有1个物品的时候,最开始的一维数组。
res_pre = [0]
#注意这里为了与列表中物品的重量一致,需要从1到w+1开始循环
for i in range(1,W+1):
    if i < w_list[0]:
        res_pre.append(0)
    else:
        res_pre.append(v_list[0])

#开始滚动更新一维数组
for n in range(1,N):
    res = [0]
    for w in range(1,W+1):
        if w - w_list[n] < 0:
            res.append(res_pre[w])
        else:
            res.append(max(res[w - w_list[n]] + v_list[n],res_pre[w]))
    # 将新的一行,赋值给res_pre
    res_pre = res
print(res_pre[-1])
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容