美文网首页
完全背包问题

完全背包问题

作者: 小碧小琳 | 来源:发表于2018-10-14 22:35 被阅读0次

    相比于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])
    

    相关文章

      网友评论

          本文标题:完全背包问题

          本文链接:https://www.haomeiwen.com/subject/diztzftx.html