最近在温习算法常识写下这篇文章帮忙本人了解记忆

01 背包问题

01背包问题的指标是在固定的容量限度内,达到最大的物品价值
01对含意:无奈宰割物品
01背包问题通常有暴力回溯法和动静布局两种形式来解决

Brute Force

回溯法查看所有组合 工夫复杂度为指数级
很容易工夫就爆表,这里就不看了

动静布局

动静布局的外围在于寻找子问题,在这个题中咱们首先去寻找子问题

寻找子问题

假如背包最大分量为5
物品信息如下

分量价值
物品147
物品235
物品356
物品433
物品528

dp表的每一个地位存储的是这么大的背包,最大收益是多少
咱们首先思考,如果只有物品1, 如果装不下,收益就是0
如果咱们的背包能够装下,那么最大收益就是7,咱们更新第一行

012345
物品1000077
物品2
物品3
物品4
物品5

通过解决子问题取得到全局问题的解

当初思考物品2,如果装不下,收益就是上一行雷同地位的后果

如果能装下:判断上一行雷同地位的后果 此物品价值加上上一行去掉此物品分量后的分量最多能装的价值
由此咱们取得状态转移方程

dp[i][j] = max(dp[i-1][j], dp[i-1][j-weight[i]]+values[i])
012345
物品100 (4 - weight of item 2)0077
物品20005max(7, (5 + 0))
物品3
物品4
物品5

一直迭代

012345
物品1000077
物品2000577
物品3000577
物品4000577
物品50088813

最初后果为13

残缺Python代码如下

## 代码中的类名、办法名、参数名曾经指定,请勿批改,间接返回办法规定的值即可## 计算01背包问题的后果# @param V int整型 背包的体积# @param n int整型 物品的个数# @param vw int整型二维数组 第一维度为n,第二维度为2的二维数组,vw[i][0],vw[i][1]别离形容i+1个物品的vi,wi# @return int整型#class Solution:    def knapsack(self, V: int, n: int, vw: List[List[int]]) -> int:        # write code here        dp = [[0] * (V + 1) for _ in range(n)]        for i in range(V + 1):            if i >= vw[0][0]:                dp[0][i] = vw[0][1]        for i in range(1, n):            for j in range(V + 1):                if j < vw[i][0]:                    dp[i][j] = dp[i-1][j]                else:                    dp[i][j] = max(dp[i-1][j], dp[i-1][j-vw[i][0]]+vw[i][1])        return dp[n-1][V]