两种背包尺寸的多维成本0-1背包问题

Posted

技术标签:

【中文标题】两种背包尺寸的多维成本0-1背包问题【英文标题】:multi-dimensional cost 0-1 knapsack problem with two backpack sizes 【发布时间】:2020-07-19 13:39:02 【问题描述】:

我正在查看在 leetcode 上找到的此问题的解决方案。

问题说明:

给定一个数组 strs,其字符串仅由 01 组成。还 两个整数mn

现在你的任务是找出你能找到的最大字符串数 用给定的m 0s 和n 1s 的形式。每个01最多只能使用一次。

输入strs = ["10","0001","111001","1","0"]m = 5n = 3

输出4

说明:这总共是4个字符串,可以用 5 个 0 和 3 个 1,分别是 "10","0001","1","0"。

用于解决问题的算法如下:

def findMaxForm(strs, m, n):

    dp = [[0] * (n + 1) for _ in range(m +1)]
    
    for s in strs:
        
        zeros, ones = s.count('0'), s.count('1')
        
        for i in range(m, zeros - 1, -1):
            
            for j in range(n, ones -1, - 1):
                
                # dp[i][j] indicates it has i zeros ans j ones,
                # can this string be formed with those ?
                
                dp[i][j] = max( 1 + dp[i - zeros][j - ones], dp[i][j])
                
            # print(dp)
            
    return dp[-1][-1]

问题中令人困惑的部分是dp[i][j] = max( 1 + dp[i - zeros][j - ones], dp[i][j])。我不确定这里发生了什么。为什么我们从零中减去 i,从一中减去 j?

我还找到了一个图表,它解释了 dp 表应如何查找数组中的任何元素。

我的问题:

第一个表代表什么? x 和 y 轴?为什么有这么多1。我想如果我理解这部分,可能会点击。如果有人通过图表,我将不胜感激 为什么这种方式给了我们最大数量的0's 和1's 可以形成?我想我仍然对这部分感到困惑dp[i][j] = max( 1 + dp[i - zeros][j - ones], dp[i][j])。 此外,该解决方案被描述为“针对 2D 空间优化的 3d-DP:dp[j][k]:i 维度被优化为就地使用”。这是什么意思?

【问题讨论】:

我知道dp[i][j] 正在做什么,但不知道为什么要这样做。例如,为什么01 的第一个值可以分解为 1 个 0 和 1 个 1,为什么在 dp 表中没有第 0 行的地方到处都是全 1。第一个值代表什么表?你可以用 1 个零和 1 个 1 组成多少个字符串?第 2 行第 3 列的 1 表示什么? 【参考方案1】:

当你遇到一个字符串s,你基本上有两种选择。它要么属于最大解,要么不属于。

如果这样做,集合的大小会增加 1,但您可以使用的 1 和 0 会减少。如果你不使用它,集合的大小保持不变,但如果左一和零,数字也是如此。

dp 代表了到目前为止,对于不同数量的“左”和“0”,您可以获得的最大此类集合。例如。 dp[m][n] 表示到目前为止您可以通过m 零和n 获得的最佳价值。同样,对于dp[2][3],其余字符串可以使用 2 个零和 3 个 1。

让我们把它包装起来:

对于一些给定数量的零 (i) 剩余使用,一些数量的零 (j) 剩余使用,以及一个字符串 s

1 + dp[i - zeros][j - ones] 表示您决定的最大集合 将 s 添加到集合中(剩下的 1 和 0 更少) dp[i][j] 表示你没有接受这个元素,继续前进。

当您在两个值上调用 max() 时,您基本上是在说:我想要这两个选项中更好的一个。

我希望这能回答前两个问题,为什么它是最大的以及 dp 线的含义。


此外,该解决方案被描述为“针对 2D 空间优化的 3d-DP: dp[j][k]: i 维度被优化以在原地使用。” 什么 那是什么意思?

在这里,您遇到了 3d 问题:您迭代的字符串本身 - 但您没有数组的另一个维度。您将其优化为就地,因为您始终只需要前一个字符串,而不需要比它“旧”的东西,从而为您节省宝贵的空间。

【讨论】:

谢谢!最后一个问题,为什么我们要从我们拥有的 0 的数量中减去 i 而从我们拥有的 1 的数量中减去 j跨度> @VickTree 您不是在减去 i 和 j,而是从零和一 (zeros, ones = s.count('0'), s.count('1')) - 您使用的零和一的数量...您正在从 中减去> ij,分别是你剩下的 1 和 0 的数量。

以上是关于两种背包尺寸的多维成本0-1背包问题的主要内容,如果未能解决你的问题,请参考以下文章

动态规划01背包问题_两种解法

多维背包问题

背包问题之0-1背包

0-1背包的贪心算法

0x52. 动态规划 - 背包(习题详解 × 19)

0-1背包问题 —— 四种解法解题