mirror of
https://github.com/krahets/hello-algo.git
synced 2025-07-05 13:15:30 +08:00
Bug fixes and improvements (#1298)
* Fix is_empty() implementation in the stack and queue chapter * Update en/CONTRIBUTING.md * Remove "剩余" from the state definition of knapsack problem * Sync zh and zh-hant versions * Update the stylesheets of code tabs * Fix quick_sort.rb * Fix TS code * Update chapter_paperbook * Upload the manuscript of 0.1 section * Fix binary_tree_dfs.rb * Bug fixes * Update README * Update README * Update README * Update README.md * Update README * Sync zh and zh-hant versions * Bug fixes
This commit is contained in:
@ -18,15 +18,15 @@
|
||||
|
||||
**第一步:思考每轮的决策,定义状态,从而得到 $dp$ 表**
|
||||
|
||||
对于每个物品来说,不放入背包,背包容量不变;放入背包,背包容量减小。由此可得状态定义:当前物品编号 $i$ 和剩余背包容量 $c$ ,记为 $[i, c]$ 。
|
||||
对于每个物品来说,不放入背包,背包容量不变;放入背包,背包容量减小。由此可得状态定义:当前物品编号 $i$ 和背包容量 $c$ ,记为 $[i, c]$ 。
|
||||
|
||||
状态 $[i, c]$ 对应的子问题为:**前 $i$ 个物品在剩余容量为 $c$ 的背包中的最大价值**,记为 $dp[i, c]$ 。
|
||||
状态 $[i, c]$ 对应的子问题为:**前 $i$ 个物品在容量为 $c$ 的背包中的最大价值**,记为 $dp[i, c]$ 。
|
||||
|
||||
待求解的是 $dp[n, cap]$ ,因此需要一个尺寸为 $(n+1) \times (cap+1)$ 的二维 $dp$ 表。
|
||||
|
||||
**第二步:找出最优子结构,进而推导出状态转移方程**
|
||||
|
||||
当我们做出物品 $i$ 的决策后,剩余的是前 $i-1$ 个物品的决策,可分为以下两种情况。
|
||||
当我们做出物品 $i$ 的决策后,剩余的是前 $i-1$ 个物品决策的子问题,可分为以下两种情况。
|
||||
|
||||
- **不放入物品 $i$** :背包容量不变,状态变化为 $[i-1, c]$ 。
|
||||
- **放入物品 $i$** :背包容量减少 $wgt[i-1]$ ,价值增加 $val[i-1]$ ,状态变化为 $[i-1, c-wgt[i-1]]$ 。
|
||||
@ -41,7 +41,7 @@ $$
|
||||
|
||||
**第三步:确定边界条件和状态转移顺序**
|
||||
|
||||
当无物品或无剩余背包容量时最大价值为 $0$ ,即首列 $dp[i, 0]$ 和首行 $dp[0, c]$ 都等于 $0$ 。
|
||||
当无物品或背包容量为 $0$ 时最大价值为 $0$ ,即首列 $dp[i, 0]$ 和首行 $dp[0, c]$ 都等于 $0$ 。
|
||||
|
||||
当前状态 $[i, c]$ 从上方的状态 $[i-1, c]$ 和左上方的状态 $[i-1, c-wgt[i-1]]$ 转移而来,因此通过两层循环正序遍历整个 $dp$ 表即可。
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
**背包问题**
|
||||
|
||||
- 背包问题是最典型的动态规划问题之一,具有 0-1 背包、完全背包、多重背包等变种。
|
||||
- 0-1 背包的状态定义为前 $i$ 个物品在剩余容量为 $c$ 的背包中的最大价值。根据不放入背包和放入背包两种决策,可得到最优子结构,并构建出状态转移方程。在空间优化中,由于每个状态依赖正上方和左上方的状态,因此需要倒序遍历列表,避免左上方状态被覆盖。
|
||||
- 0-1 背包的状态定义为前 $i$ 个物品在容量为 $c$ 的背包中的最大价值。根据不放入背包和放入背包两种决策,可得到最优子结构,并构建出状态转移方程。在空间优化中,由于每个状态依赖正上方和左上方的状态,因此需要倒序遍历列表,避免左上方状态被覆盖。
|
||||
- 完全背包问题的每种物品的选取数量无限制,因此选择放入物品的状态转移与 0-1 背包问题不同。由于状态依赖正上方和正左方的状态,因此在空间优化中应当正序遍历。
|
||||
- 零钱兑换问题是完全背包问题的一个变种。它从求“最大”价值变为求“最小”硬币数量,因此状态转移方程中的 $\max()$ 应改为 $\min()$ 。从追求“不超过”背包容量到追求“恰好”凑出目标金额,因此使用 $amt + 1$ 来表示“无法凑出目标金额”的无效解。
|
||||
- 零钱兑换问题 II 从求“最少硬币数量”改为求“硬币组合数量”,状态转移方程相应地从 $\min()$ 改为求和运算符。
|
||||
|
Reference in New Issue
Block a user