1. 背包问题概述
背包问题是算法领域中经典的动态规划问题,主要研究在有限容量的背包中如何选择物品以获得最大价值。根据物品选取规则的不同,主要分为0-1背包和完全背包两种基本类型。
0-1背包问题中,每种物品只能选择放入(1)或不放入(0)背包一次;而完全背包问题则允许同一物品被无限次选取。这两种问题在实际应用中广泛存在,从资源分配到投资组合优化都能看到它们的身影。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 0-1背包问题详解
2.1 问题定义与数学模型
给定一个容量为W的背包和N件物品,每件物品有重量w_i和价值v_i。要求在不超过背包容量的前提下,选择物品使得总价值最大。其数学模型可表示为:
max Σ(v_i * x_i)
s.t. Σ(w_i * x_i) ≤ W
x_i ∈
2.2 动态规划解法
2.2.1 状态定义
定义dp[i][j]表示考虑前i件物品,背包容量为j时能获得的最大价值。
2.2.2 状态转移方程
对于第i件物品,有两种选择:
- 不放入:dp[i][j] = dp[i-1][j]
- 放入:dp[i][j] = dp[i-1][j-w_i] + v_i
因此状态转移方程为:
dp[i][j] = max(dp[i-1][j], dp[i-1][j-w_i] + v_i)
2.2.3 初始化
dp[0][j] = 0 (0 ≤ j ≤ W)
dp[i][0] = 0 (0 ≤ i ≤ N)
2.3 空间优化
观察状态转移方程发现,当前状态只与上一行状态有关,因此可将二维数组优化为一维数组:
python复制def knapsack_01(W, weights, values):
n = len(weights)
dp = [0] * (W + 1)
for i in range(n):
for j in range(W, weights[i]-1, -1):
dp[j] = max(dp[j], dp[j-weights[i]] + values[i])
return dp[W]
注意:内层循环必须逆序遍历,避免同一物品被多次选取。
2.4 时间复杂度分析
时间复杂度:
