Loading,你用IE,难怪你打不开

背包问题动态规划

状态定义:dp[i][j] 表示前 i 件物品,在分配了总容量 j 时,能获得的最大价值。
这是动态分配的核心状态表,每一个格子都对应一个子资源规模下的最优分配方案。
状态转移方程(分配决策逻辑):
image
沿用示例参数:
物品数量 n=4
重量数组 w=[2,3,4,5]
价值数组 v=[3,4,5,6]
背包总容量 C=8
状态定义:dp[i][j] = 前 i 件物品、背包容量为 j 时,能获得的最大价值。

一、完整 DP 状态表(最终结果)
image

二、逐行(逐阶段)动态分配推导过程
阶段 0:初始化(i=0,无物品)
没有任何物品可分配,无论容量多大,价值都为 0,这是递推的边界条件。
dp[0][j]=0,∀j∈[0,8]

阶段 1:处理第 1 件物品(w=2, v=3)

对每个容量 j 决策:是否分配容量给物品 1。
-当 j<2:容量不足,无法装入,继承上一阶段结果:dp[1][j]=dp[0][j]=0
-当 j≥2:取「不装」和「装」的最大值
dp[1][j]=max(dp[0][j], dp[0][j−2]+3)
例如 j=2:max(0, 0+3)=3;j=8:max(0, 0+3)=3

阶段 2:处理第 2 件物品(w=3, v=4)

j=0,1,2: 容量不足 3,继承上一行:dp[2][j]=dp[1][j]
j=3: max(dp[1][3]=3, dp[1][0]+4=4)⇒4
j=5: max(dp[1][5]=3, dp[1][2]+4=3+4=7)⇒7
j=8: max(dp[1][8]=3, dp[1][5]+4=3+4=7)⇒7

阶段 3:处理第 3 件物品(w=4, v=5)

在阶段 2 的基础上,重新决策是否分配容量给物品 3。
j=0∼3:容量不足 4,继承上一行
j=4: max(dp[2][4]=4, dp[2][0]+5=5)⇒5
j=6: max(dp[2][6]=7, dp[2][2]+5=3+5=8)⇒8
j=7: max(dp[2][7]=7, dp[2][3]+5=4+5=9)⇒9
j=8: max(dp[2][8]=7, dp[2][4]+5=4+5=9)⇒9

阶段 4:处理第 4 件物品(w=5, v=6)

在阶段 3 的基础上,重新决策是否分配容量给物品 4。
j=0∼4:容量不足 5,继承上一行
j=5: max(dp[3][5]=7, dp[3][0]+6=6)⇒7
j=8: max(dp[3][8]=9, dp[3][3]+6=4+6=10)⇒10

一、回溯判断规则
从右下角 dp[i=4][j=8] 开始,逆序逐个物品判断:
若 dp[i][j] == dp[i-1][j]:说明第 i 件物品没有装入,直接查看上一件物品,容量 j 不变。
若 dp[i][j] > dp[i-1][j]:说明第 i 件物品被装入了,记录该物品,将剩余容量减去该物品重量 j = j - w[i],再查看上一件物品。
当 i=0(所有物品判断完毕)或 j=0(容量用完)时,回溯结束。

二、逐步骤回溯推导
第 1 步:判断第 4 件物品(w=5, v=6)
当前状态:i=4,j=8
dp[4][8] = 10,dp[3][8] = 9
10 ≠ 9 → 第 4 件物品装入背包
记录装入:4 号物品(重量 5,价值 6)
剩余容量:j = 8 - 5 = 3
继续判断上一件:i=3

第 2 步:判断第 3 件物品(w=4, v=5)
当前状态:i=3,j=3
dp[3][3] = 4,dp[2][3] = 4
4 = 4 → 第 3 件物品不装入
容量不变,继续判断上一件:i=2
第 3 步:判断第 2 件物品(w=3, v=4)
当前状态:i=2,j=3
dp[2][3] = 4,dp[1][3] = 3
4 ≠ 3 → 第 2 件物品装入背包
记录装入:2 号物品(重量 3,价值 4)
剩余容量:j = 3 - 3 = 0
容量已用完,回溯直接结束。

三、最终装箱方案
装入的物品
2 号物品:重量 3,价值 4
4 号物品:重量 5,价值 6
结果验证
总重量:3 + 5 = 8,恰好占满背包全部容量
总价值:4 + 6 = 10,与 DP 表最终计算的最大价值完全一致
在该示例中,这是唯一能达到最大价值 10 的装箱方案。

posted @ 2026-06-30 11:03  老板娘的神秘商店  阅读(12)  评论(0)    收藏  举报