在完全背包和多重背包部分我是按照自己思路来写的,如果有问题,请指出!感谢!
背包问题是动态规划中一种比较典型的题型,大体可以分成3类01背包,完全背包以及多重背包
一、01背包
问题描述:
有n种物品,每种只有1个。第i中物品的体积为 v i v_i vi,重量为 w i w_i wi。选一些物品装到一个容量为C的背包中,使得背包内的物品的总体积不超过C的前提下,重量尽可能的大
二维解法
最简单的思路就是使用二位状态dp[i][j]来表示装了i个物品时,体积为j的情况下所能获得的最大重量。
状态转移如下:
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v[i]] + w[i])
也就是选择装如第i个物品或不装入第i个物品所得到重量的较大值。
for i in range(1, n+1):
for j in range(C+1):
if v[i] < j:
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v[i]] + w[i])
一维解法
根据二维解法中的转移方程可以发下,装到第i个物品时所能得到的最大重量仅与装到i-1时有关,所以可以进行状态压缩
dp[j] = max(dp[j], dp[j - v[i]] + w[i])
for i in range(n):
for j in range(C+1):
if v[i] < j:
dp[j] = max(dp[j], dp[j - v[i]] + w[i])
二、完全背包
问题描述:
与01背包类似,但是每一类的物品有无限个
解决方案
状态转移方程和01背包相同:
dp[j] = max(dp[j], dp[j - v[i]] + w[i])
for j in range(C+1):
for i in range(n):
if v[i] < j:
dp[j] = max(dp[j], dp[j - v[i]] + w[i])
贪心
在完全背包问题中,因为没有了个数的限制,我们只需要可以先计算出密度,优先选取密度大的物品即可,这样复杂度要远小于动态规划。
三、多重背包
问题描述:
多重背包是在完全背包的基础上加了一层数量的限制,第i种物品的数量为 n i n_i ni
解决方案
解决的办法与完全背包相似,只需要在遍历的时候判断是否还有物品剩余即可
dp[j] = max(dp[j], dp[j - v[i]] + w[i])
for j in range(C+1):
last = -1
for i in range(n):
if v[i] < j and n[i]:
if dp[j] < dp[j - v[i]] + w[i]:
dp[j] = dp[j - v[i]] + w[i]
last = i
if last:
n[i] -= 1