力扣 —— 动态规划(背包问题)
背包问题
01背包
注:01背包里物品只有一个
物品为:
重量 | 价值 | |
物品0 | 1 | 2 |
物品1 | 2 | 4 |
物品2 | 3 | 4 |
物品3 | 4 | 5 |
问背包能背的物品最大价值是多少?
首先确定dp数组以及下标的含义:dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少。
然后确定递推公式:
明确有哪些方向可以推导出 dp[i][j]
放物品i & 不放物品i
不放物品i:背包容量为j,里面不放物品i的最大价值是dp[i - 1][j]。
放物品i:背包空出物品i的容量后,背包容量为j - weight[i],dp[i - 1][j - weight[i]] 为背包容量为j - weight[i]且不放物品i的最大价值,那么dp[i - 1][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最大价值
递归公式: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
最后dp数组如何初始化:
import xbot
from xbot import print, sleep
from .import package
from .package import variables as glvdef main(args):n, bagweight = 4, 5 # 示例输入:4个物品,背包容量为5weight = [1, 2, 3, 4] # 每个物品的重量value = [2, 4, 4, 5] # 每个物品的价值dp = [[0] * (bagweight+1) for j in range(n)]# print(dp)# 初始化动态规划表# for(int i=0 ; i <= bagweight ; i++){# dp[i][0] = 0;# }# for(int j=weight[0] ; j<=bagweight ; j++){# dp[0][j]=value[0]# }for i in range(n):dp[i][0]=0for j in range(weight[0],bagweight+1):dp[0][j]=value[0]# 先遍历物品for i in range(1,n):# 遍历重量for j in range(bagweight+1):if j < weight[i]:# 背包重量达不到物品i的重量,不放物品idp[i][j] = dp[i-1][j]else:# 能达到放物品i的重量# 分别是放物品i 和 不放物品i,我们要取最大值# 背包空出物品i的容量后,背包容量为j - weight[i]dp[i][j] = max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i])# 输出结果print("最大价值:", dp[n - 1][bagweight])