leetcode-背包问题

 


问题描述

给你一个装载重量为 W 的背包和 N 个物品,每个物品有重量和价值两个属性。其中第 i 个物品的重量为 wt[i],价值为 val[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 个物品装入背包,那么很显然,最大价值 dp[i][w]=dp[i1][w],继承之前的结果。

如果把这第 i 个物品装入了背包,那么 dp[i][w]=dp[i1][wwt[i1]]+val[i1].
若装了第 i 个物品,就要寻求剩余重量 wwt[i1] 限制下的最大价值,加上第 i 个物品的价值 val[i1]

代码实现

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]

参考

posted @   topbookcc  阅读(227)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
/* 鼠标点击求赞文字特效 */
点击右上角即可分享
微信分享提示