Lazy loaded image
动态规划2-0/1背包问题
Words 1442Read Time 4 min
2026-3-2
2026-3-2
type
Post
status
Published
date
Mar 2, 2026
slug
summary
tags
算法笔记
category
笔记
icon
password
Video preview
通过视频学习,我了解到解决0/1背包问题通常有两种方法:一个是集合法,一个是表格法
下面来一个例子
  • 你有一个背包,容量最大为 4 公斤。
    • 物品
      重量(kg)
      价值(元)
      A
      1
      15
      B
      3
      20
      C
      4
      30
      面前有几件物品,每件只能拿(1)或不拿(0)——这就是“01”的含义。目标是如何装包,让总价值最高。

方法一:集合法(暴力搜索 / 回溯法)

这是最符合人类直觉的方法,核心思想是把所有可能的组合列出来,然后找给定容量里价值最大那个。这就好比对于每个物品做一个选择——拿/不拿。
因此我们列出所有的这种集合
  1. {}———此时为空包,价值和重量为0。
  1. {A}———重量1,价值15。
  1. {B}———重量3,价值20。
  1. {C}———重量4,价值30。
  1. {A,B}———重量4,价值35。
  1. {A, C} -> 重量5 。
  1. {B, C} -> 重量7 。
  1. {A, B, C} -> 重量8 。
分析以上组合我们可以排除重量超过4公斤的组合,然后挑出价值最高的组合第5组{A, B},价值 35 元。
🌟
总结
优点:思路简单,像列举法。
缺点:物品一多就“爆炸”。每多一件物品,组合数就翻一倍。10件物品就有1024种组合,100件物品的话,全宇宙的计算机算到宇宙灭亡都算不完。

方法二:表格法(动态规划标准解法)

🌟
我们不再考虑具体的物品组合,而是通过一系列更小的问题,去把答案记在一张表格里,然后去高效的解决更复杂的问题。
这是动态规划的经典解法之一,核心是“记笔记”和“用之前的答案推新答案”,避免重复计算。
还是那个例子,我们设计一个表格记录答案来解决问题。
  • row(i)——代表“只考虑前i件物品”。比如说i=2,此时我们只考虑物品A和B。
  • column(j)——代表”背包当前的容量从 0 到 4(我们的背包总容量)。
  • 单元格dp[i][j]的值——代表的是在”只考虑前i件商品,背包当前容量为j“的条件下,我们能获得的最大价值。
表格法
我们开始填表,规则只有一条
面对第i件物品,在容量j下,我们只需要考虑:
概括来说就是,对于dp[i][j]:
  • 不拿这件物品的话,那么价值就等于”没考虑它时,同等容量下的最大价值“,即dp[i-1][j]。
  • 拿这件物品的话(前提是背包装得下),那么价值就等于”这件物品的价值“+”没选择它时,剩余容量下的背包最大价值“,即物品价值 + dp[i-1][j-物品重量]
  • 我们永远选择两者中价值更大的那个max(不拿的价值, 拿的价值)
开始填:
  1. 初始化,此时i=0,j=0。
    1. 代表:”一件物品都不考虑“,可想而知此时任何容量下价值都为0。
    2. 0
      1
      2
      3
      4
      0
      0
      0
      0
      0
      0
      1
      2
      3
  1. i=1,即只考虑物品A
    1. j=0(容量0)——装不下A,价值为0。
    2. j=1,2,3,4——都能装下A,价值都是15。
    3. 0
      1
      2
      3
      4
      0
      0
      0
      0
      0
      0
      1
      0
      15
      15
      15
      15
      2
      3
  1. i=2,即考虑物品A和B(A+B容量为4),即前2件商品———关键
    1. 我们看 dp[2][4](考虑A和B,容量为4):
      • 不拿B:价值等于 dp[1][4] = 15
      • 拿B:B价值20 + dp[1][4-3]= 20 + dp[1][1]= 20 + 15 = 35
      • max(15, 35) = 35我们就在这里找到了最优解!
      同理我们看dp[2][2] :
      • 不拿B:价值等于 dp[1][2] = 15
      • 拿B:B价值等于20 + dp[1][2-3]= 20 + dp[1][-1]。背包容量不够,dp值不变。
      同理我们看dp[2][3] :
      • 不拿B:价值等于 dp[1][3] = 15
      • 拿B:B价值等于20 + dp[1][3-3]= 20 + dp[1][0]=20。
      0
      1
      2
      3
      4
      0
      0
      0
      0
      0
      0
      1
      0
      15
      15
      15
      15
      2
      0
      15
      15
      20
      35
      3
  1. i=3,即考虑物品A和B以及C(A+B+C容量为8)。
    1. 由上面可知,我们背包容量合计为4,装不下C,故dp值不变
      0
      1
      2
      3
      4
      0
      0
      0
      0
      0
      0
      1
      0
      15
      15
      15
      15
      2
      0
      15
      15
      20
      35
      3
      0
      15
      15
      20
      35
🌟
表格法总结
  • 优点:效率极高!我们只进行了 (物品数 × 容量) 次计算。100件物品,容量1000,也只需计算10万次。
  • 缺点:思路不那么直观,需要理解“状态”和“转移”的概念。
  • 精髓:表格的右下角 dp[3][4]就是全局最优解。这个35,并不是凭空算的,而是由前面更小、更简单的问题答案(15,20等)像搭积木一样组合出来的,并且每个答案只计算一次。

最后

两种方法的灵魂对比:
假设你要解决“用前3件物品装满4kg背包”这个大问题 (dp[3][4]):
  • 集合法:直接冲进仓库,面对3件物品开始疯狂尝试各种排列组合。
  • 表格法
      1. 先问:“如果只有1件物品,在容量1/2/3/4下怎么办?” 把答案写在本子(dp表)第一行。
      1. 再问:“在有前1件物品答案的基础上,加入第2件物品会怎样?” 利用第一行的答案,算出第二行的答案。
      1. 最后问:“在有前2件物品答案的基础上,加入第3件物品会怎样?” 利用第二行的答案,轻松算出最终答案。
一句话总结
  • 集合法“是什么?” —— 直接寻找那个正确的集合。
  • 表格法“如何从更简单的情况变过来?” —— 通过记录和推导所有小问题的答案,来构建大问题的答案。这就是动态规划的智慧。
上一篇
动态规划1-动态规划简述
下一篇
从 Heo 到 Heo Pro