动态规划入门-完全背包与多重背包问题

物品不止有一个的情况,物品不止有一个也分两种。
一种是不作任何限制,要多少有多少,这种称为完全背包问题;
另一种是依然有个数限制,这种称为多重背包问题。

一、完全背包

在背包问题当中,背包的容量是状态,而选择哪个物品进行获取则是决策,当我们制定了一个决策之后,背包会从一个状态转移到另一个状态。而动态规划算法就是枚举所有状态和决策,获得所有的状态转移,并且记录这个过程中每个状态能够获得的最优解

在完全背包问题当中,我们去掉了个数的限制,也就意味着决策之间不再有后效性,一个决策可以重复应用在各个状态当中

整个算法其实非常简单,几乎就是零一背包的代码。只不过我们把其中倒叙遍历的背包状态再”修正“回来。

之前我们为了避免物品的重复获取,所以采用了倒叙遍历的方法,如今我们不再对数量进行限制,意味着我们可以自由地采取决策进行转移。要做到这点,其他的代码都不用修改,只需要将第二重循环枚举的状态,再换成从0开始的正向遍历即可。

dp = [0 for _ in range(11)]

items = [[6, 10], [5, 8], [5, 9]]

# 遍历物品
for v, w in items:
# 遍历背包空间(状态)
# 更新vp+v的状态,即当前容量放入物品之后的状态
for vp in range(0, 10-v+1):
 dp[vp+v] = max(dp[vp+v], dp[vp] + w)

print(max(dp]))

在第一种循环当中,我们遍历了所有的物品,每一个物品对应了一种决策。每一个决策可以应用在各个状态上。

在完全背包当中,由于所有的物品都可以无限获取。所以我们可以引入一些零一背包不能进行的优化,比如对于同样体积的物品而言,我们可以只保留价值最高的物品,将其他的物品过滤掉。这个思路很朴素,我想大家应该都能理解。

比如两个物品体积都是3,一个价值是4,另一个价值是3,我们完全可以忽略价值是3的那一种。因为两者带来的状态转移是一样的,但是明显前者收益更好。而这个优化在零一背包当中不可行是因为每个物品只有一个,很有可能会出现两者都要的情况。在完全背包当中则没有这个问题。


二、多重背包


参考文章:

  1. 一篇公众号文章

你可能感兴趣的:(LeetCode分类刷题,#,LeetCode动态规划)