Skip to content

knapsack01

解决经典的0-1背包问题,在限定的总重量内选择物品使得总价值最大,每个物品只能选择一次。

输入配置

物品1
重量: 2
价值: 3
物品2
重量: 3
价值: 4
物品3
重量: 4
价值: 5
物品4
重量: 5
价值: 6

执行过程

步骤 1 / 24
初始化DP表,dp[i][w]表示前i个物品在容量w时的最大价值
物品\容量012345678
0000000000
1000000000
2000000000
3000000000
4000000000
当前单元格
来源单元格
最终结果

算法说明

0-1背包问题:在限定容量内选择物品使总价值最大,每个物品只能选0或1次。使用动态规划求解,时间复杂度O(n×W)。

函数签名

typescript
function knapsack01(
  items: KnapsackItem[],
  capacity: number,
  includeDpTable?: boolean
): KnapsackResult

interface KnapsackItem {
  name?: string
  weight: number
  value: number
}

interface KnapsackResult {
  maxValue: number
  selectedItems: number[]
  dpTable?: number[][]
}

参数

参数名类型必填说明
itemsKnapsackItem[]物品数组,每个物品包含重量和价值
capacitynumber背包容量
includeDpTableboolean是否在结果中包含DP表(用于调试),默认false

KnapsackItem 结构:

属性类型必填说明
namestring物品名称(用于显示)
weightnumber物品重量
valuenumber物品价值

返回值

类型说明
KnapsackResult背包问题结果对象

KnapsackResult 结构:

属性类型说明
maxValuenumber在限定容量内可获得的最大价值
selectedItemsnumber[]选中的物品索引数组
dpTablenumber[][]DP表(可选,仅当includeDpTable为true时)

工作原理

  1. 创建DP表: 创建一个 (n+1) × (capacity+1) 的二维数组,其中 n 是物品数量
  2. 填充DP表: 对每个物品和每个容量,决定是否选择该物品
    • 不选择: dp[i][w] = dp[i-1][w]
    • 选择: dp[i][w] = dp[i-1][w-weight] + value
    • 取两者最大值
  3. 回溯找出选中物品: 从 dp[n][capacity] 开始回溯,判断每个物品是否被选中
  4. 返回结果: 返回最大价值和选中的物品索引

时间复杂度: O(n×W),其中 n 是物品数量,W 是背包容量
空间复杂度: O(n×W)