美文网首页动态规划
LeetCode 动态规划专题 6:0-1 背包问题在空间复杂度

LeetCode 动态规划专题 6:0-1 背包问题在空间复杂度

作者: 李威威 | 来源:发表于2019-05-28 23:17 被阅读5次

0-1 背包问题说的是这样一个问题:给定 n 个物品,还有这些物品对应的价值和重量。你有一个背包,背包限制重量 C ,问你最多拿走的价值最多是多少的物品。这是一个带有约束的最优化问题,是动态规划能解决的问题。

第 1 步:定义状态。

F(i,C) 的定义:考虑将索引的区间是 [0,...,i] 内的物品放进容积为 C 的背包,使得价值最大。注意:考虑将这 i + 1 个物品放进容量为 C 的背包,使得价值最大。

第 2 步:推导出状态转移方程。于是对于 i=0,...,n-1F(i,C) 有以下两种方案:

1、第 i 个物品没有被选择,则 F(i-1,C) 为所求;

2、第 i 个物品被选择,则 v(i) + F(i-1,C-w(i)) 为所求。

综合以上两点:F(i,c) = max(F(i-1,c),v(i)+F(i-1,c-w(i)) 为所求,这个方程就称为状态转移方程。

时间复杂度:O( n * C )
空间复杂度:O( n * C )

我们这一节从空间复杂度进行优化。

优化1:基于第 i 行元素只依赖于第 i-1 行元素

由于第 i 行元素只依赖于第 i-1 行元素。理论上,只需要保持两行元素就可以了,为此我们采用“滚动变量”的方式。

Python 代码:

class Solution:
    def knapsack01(self, weights, values, capacity):
        '''
        一行一行填表
        # 填写第 0 行(只有 index = 0 这个物品)的时候,就看这个 index 的物品是否能放进背包
        # 如果可以放进背包,就是此时的最大价值


        :param weights:
        :param values:
        :param index:
        :param capacity:
        :return:
        '''

        l = len(weights)
        if l == 0:
            return 0
        dp = [[-1 for _ in range(capacity + 1)] for _ in range(2)]  # 我们只须要 2 行
        for i in range(capacity + 1):
            if weights[0] <= i:
                dp[0][i] = values[0]
            else:
                dp[0][i] = 0
        # 只要遇到 dp 跟 i 相关的索引的部分,都取 mod 2 的余数
        for i in range(1, l):
            for j in range(capacity + 1):
                dp[i % 2][j] = dp[(i - 1) % 2][j]
                if weights[i] <= j:
                    dp[i % 2][j] = values[i] + dp[(i - 1) % 2][j - weights[i]]
        return dp[(l - 1) % 2][-1]

优化2:如何将二维降到一维

依据:后面依赖前面的,因此,我们从右边向左边填写,所以可以用一行注意到:每一行的更新只和它左边的元素有关,我们把空间压缩到一行,执行动态规划的时候,从右边到左边更新就可以了。

Python 代码:

class Solution:
    def knapsack01(self, weights, values, capacity):
        '''
        :param weights:
        :param values:
        :param index:
        :param capacity:
        :return:
        '''

        l = len(weights)
        if l == 0:
            return 0
        # 我们只须要 1 行
        dp = [-1 for _ in range(capacity + 1)]
        for i in range(capacity + 1):
            if weights[0] <= i:
                dp[i] = values[0]
            else:
                dp[i] = 0
        for i in range(1, l):
            for j in range(capacity, -1, -1):
                if weights[i] <= j:
                    dp[j] = max(dp[j], values[i] + dp[j - weights[i]])
        return dp[-1]

(本节完)

相关文章

  • LeetCode 动态规划专题 6:0-1 背包问题在空间复杂度

    0-1 背包问题说的是这样一个问题:给定 个物品,还有这些物品对应的价值和重量。你有一个背包,背包限制重量 ,...

  • 动态规划

    0-1背包问题 自己实现的0-1背包问题的动态规划解法,先贴上吧,动态规划原理解释有空再写。

  • 初识动态规划

    0-1 背包问题 备忘录 动态规划-二维数组 动态规划-一维数组 0-1 背包问题升级版 回溯算法 动态规划-二维...

  • 数据结构与算法笔记day23:动态规划

    1初识动态规划 这节课的内容不涉及动态规划的理论,而是通过两个例子:0-1背包问题、0-1背包问题升级...

  • Algorithm进阶计划 -- 动态规划(下)

    经典动态规划背包问题最长子序列问题 1. 背包问题 1.1 0-1 背包问题 0-1 背包问题,描述如下: 上面...

  • 算法-动态规划-背包问题

    背包问题是基础的动态规划问题,包含了0-1背包,完全背包,多重背包等。 0-1背包 存在容量为 的背包 , 件体...

  • LeetCode 动态规划专题 5:0-1 背包问题

    这一节我们介绍使用动态规划解决的一个非常经典的问题:0-1 背包问题。 0-1 背包问题描述 问题描述: 有一个背...

  • lintcode-k数和

    动态规划(确定0-1背包、完全背包、多重背包)0-1背包:每个元素要么出现,要么不出现,逆序遍历,数组定义为:前i...

  • 背包问题

    背包问题属于典型的动态规划问题。这里我们将详细介绍0-1背包,完全背包和多重背包问题 一、 0-1背包 有N件物品...

  • 算法3:动态规划

    5.动态规划5.1 什么是动态规划?5.2 自底向上的动态规划:5.3 自顶向下的动态规划5.4 0-1背包问题:...

网友评论

    本文标题:LeetCode 动态规划专题 6:0-1 背包问题在空间复杂度

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