leetcode-背包问题
问题描述
给你一个装载重量为 W 的背包和 N 个物品,每个物品有重量和价值两个属性。其中第 i 个物品的重量为 ,价值为 ,现在让你用这个背包装物品,最多能装的价值是多少?
示例
N = 3, W = 4 wt = [2, 1, 3] val = [4, 2, 3]
返回6,选择前两件物品,总重量小于W,可获得最大价值6.
动态规划
状态和选择
状态有两个,就是「背包的容量」和「可选择的物品」。
对于每件物品,你能选择什么?选择就是「装进背包」或者「不装进背包」
动态规划框架
for 状态1 in 状态1的所有取值: for 状态2 in 状态2的所有取值: for ... dp[状态1][状态2][... = 择优(选择1,选择2...)
明确dp含义
首先看看刚才找到的「状态」,有两个,也就是说我们需要一个二维 dp 数组。
dp[i][w]定义:对于前 i 个物品,当前背包的容量为 w,这种情况下可以装的最大价值是 dp[i][w]
比如说,如果 dp[3][5] = 6,其含义为:对于给定的一系列物品中,若只对前 3 个物品进行选择,当背包容量为 5 时,最多可以装下的价值为 6。
根据选择,状态转移
如果没有把这第 i 个物品装入背包,那么很显然,最大价值 ,继承之前的结果。
如果把这第 i 个物品装入了背包,那么 .
若装了第 i 个物品,就要寻求剩余重量 限制下的最大价值,加上第 i 个物品的价值

代码实现
def backpack(W:int, N:int,wt: List[int], val: List[int]): # dp[i][j]对于前i个物品,背包容量为j,所装的价值是dp[i][j] dp = [[0]*(W+1) for _ in range(N+1)] for i in range(1,N+1): for j in range(1,W+1): # 若不选择第i个物品 if j<wt[i-1]: dp[i][j] = dp[i-1][j] # 若选择第i个物品 else: dp[i][j] = max(dp[i-1][j-wt[i-1]]+val[i-1],dp[i-1][j]) return dp[N][W]
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异