两种背包尺寸的多维成本0-1背包问题
Posted
技术标签:
【中文标题】两种背包尺寸的多维成本0-1背包问题【英文标题】:multi-dimensional cost 0-1 knapsack problem with two backpack sizes 【发布时间】:2020-07-19 13:39:02 【问题描述】:我正在查看在 leetcode 上找到的此问题的解决方案。
问题说明:
给定一个数组
strs
,其字符串仅由 0 和 1 组成。还 两个整数m
和n
。现在你的任务是找出你能找到的最大字符串数 用给定的
m
0s 和n
1s 的形式。每个0和1最多只能使用一次。
输入:
strs = ["10","0001","111001","1","0"]
、m = 5
、n = 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')
) - 您使用的零和一的数量...您正在从 中减去> i
和 j
,分别是你剩下的 1 和 0 的数量。以上是关于两种背包尺寸的多维成本0-1背包问题的主要内容,如果未能解决你的问题,请参考以下文章