mirror of
https://github.com/krahets/hello-algo.git
synced 2026-04-04 03:00:06 +08:00
build
This commit is contained in:
@@ -22,7 +22,7 @@ comments: true
|
||||
|
||||
如图 14-6 所示,若第 $1$、$2$、$3$ 阶的代价分别为 $1$、$10$、$1$ ,则从地面爬到第 $3$ 阶的最小代价为 $2$ 。
|
||||
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-6 爬到第 3 阶的最小代价 </p>
|
||||
|
||||
@@ -300,7 +300,7 @@ $$
|
||||
|
||||
图 14-7 展示了以上代码的动态规划过程。
|
||||
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-7 爬楼梯最小代价的动态规划过程 </p>
|
||||
|
||||
@@ -545,7 +545,7 @@ $$
|
||||
|
||||
例如图 14-8 ,爬上第 $3$ 阶仅剩 $2$ 种可行方案,其中连续三次跳 $1$ 阶的方案不满足约束条件,因此被舍弃。
|
||||
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-8 带约束爬到第 3 阶的方案数量 </p>
|
||||
|
||||
@@ -567,7 +567,7 @@ dp[i, 2] = dp[i-2, 1] + dp[i-2, 2]
|
||||
\end{cases}
|
||||
$$
|
||||
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-9 考虑约束下的递推关系 </p>
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ comments: true
|
||||
|
||||
图 14-10 展示了一个例子,给定网格的最小路径和为 $13$ 。
|
||||
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-10 最小路径和示例数据 </p>
|
||||
|
||||
@@ -53,7 +53,7 @@ comments: true
|
||||
|
||||
至此,我们就得到了图 14-11 所示的二维 $dp$ 矩阵,其尺寸与输入网格 $grid$ 相同。
|
||||
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-11 状态定义与 dp 表 </p>
|
||||
|
||||
@@ -73,7 +73,7 @@ $$
|
||||
dp[i, j] = \min(dp[i-1, j], dp[i, j-1]) + grid[i, j]
|
||||
$$
|
||||
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-12 最优子结构与状态转移方程 </p>
|
||||
|
||||
@@ -89,7 +89,7 @@ $$
|
||||
|
||||
如图 14-13 所示,由于每个格子是由其左方格子和上方格子转移而来,因此我们使用采用循环来遍历矩阵,外循环遍历各行、内循环遍历各列。
|
||||
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-13 边界条件与状态转移顺序 </p>
|
||||
|
||||
@@ -368,7 +368,7 @@ $$
|
||||
|
||||
本质上看,造成重叠子问题的原因为:**存在多条路径可以从左上角到达某一单元格**。
|
||||
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-14 暴力搜索递归树 </p>
|
||||
|
||||
@@ -697,7 +697,7 @@ $$
|
||||
|
||||
如图 14-15 所示,在引入记忆化后,所有子问题的解只需计算一次,因此时间复杂度取决于状态总数,即网格尺寸 $O(nm)$ 。
|
||||
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-15 记忆化搜索递归树 </p>
|
||||
|
||||
@@ -1039,40 +1039,40 @@ $$
|
||||
数组 `dp` 大小为 $n \times m$ ,**因此空间复杂度为 $O(nm)$** 。
|
||||
|
||||
=== "<1>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<2>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<3>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<4>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<5>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<6>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<7>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<8>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<9>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<10>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<11>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<12>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-16 最小路径和的动态规划过程 </p>
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ comments: true
|
||||
|
||||
如图 14-27 所示,将 `kitten` 转换为 `sitting` 需要编辑 3 步,包括 2 次替换操作与 1 次添加操作;将 `hello` 转换为 `algo` 需要 3 步,包括 2 次替换操作和 1 次删除操作。
|
||||
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-27 编辑距离的示例数据 </p>
|
||||
|
||||
@@ -24,7 +24,7 @@ comments: true
|
||||
|
||||
从决策树的角度看,本题的目标是求解节点 `hello` 和节点 `algo` 之间的最短路径。
|
||||
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-28 基于决策树模型表示编辑距离问题 </p>
|
||||
|
||||
@@ -53,7 +53,7 @@ comments: true
|
||||
2. 删除 $s[i-1]$ ,则剩余子问题 $dp[i-1, j]$ 。
|
||||
3. 将 $s[i-1]$ 替换为 $t[j-1]$ ,则剩余子问题 $dp[i-1, j-1]$ 。
|
||||
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-29 编辑距离的状态转移 </p>
|
||||
|
||||
@@ -446,49 +446,49 @@ $$
|
||||
如图 14-30 所示,编辑距离问题的状态转移过程与背包问题非常类似,都可以看作是填写一个二维网格的过程。
|
||||
|
||||
=== "<1>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<2>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<3>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<4>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<5>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<6>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<7>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<8>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<9>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<10>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<11>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<12>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<13>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<14>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<15>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-30 编辑距离的动态规划过程 </p>
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ icon: material/table-pivot
|
||||
|
||||
<div class="center-table" markdown>
|
||||
|
||||
{ width="600" }
|
||||
{ class="cover-image" }
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ comments: true
|
||||
|
||||
如图 14-1 所示,对于一个 $3$ 阶楼梯,共有 $3$ 种方案可以爬到楼顶。
|
||||
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-1 爬到第 3 阶的方案数量 </p>
|
||||
|
||||
@@ -405,7 +405,7 @@ $$
|
||||
|
||||
这意味着在爬楼梯问题中,各个子问题之间存在递推关系,**原问题的解可以由子问题的解构建得来**。图 14-2 展示了该递推关系。
|
||||
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-2 方案数量递推关系 </p>
|
||||
|
||||
@@ -640,7 +640,7 @@ $$
|
||||
|
||||
图 14-3 展示了暴力搜索形成的递归树。对于问题 $dp[n]$ ,其递归树的深度为 $n$ ,时间复杂度为 $O(2^n)$ 。指数阶属于爆炸式增长,如果我们输入一个比较大的 $n$ ,则会陷入漫长的等待之中。
|
||||
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-3 爬楼梯对应递归树 </p>
|
||||
|
||||
@@ -975,7 +975,7 @@ $$
|
||||
|
||||
观察图 14-4 ,**经过记忆化处理后,所有重叠子问题都只需被计算一次,时间复杂度被优化至 $O(n)$** ,这是一个巨大的飞跃。
|
||||
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-4 记忆化搜索对应递归树 </p>
|
||||
|
||||
@@ -1229,7 +1229,7 @@ $$
|
||||
|
||||
图 14-5 模拟了以上代码的执行过程。
|
||||
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-5 爬楼梯的动态规划过程 </p>
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ comments: true
|
||||
|
||||
观察图 14-17 ,由于物品编号 $i$ 从 $1$ 开始计数,数组索引从 $0$ 开始计数,因此物品 $i$ 对应重量 $wgt[i-1]$ 和价值 $val[i-1]$ 。
|
||||
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-17 0-1 背包的示例数据 </p>
|
||||
|
||||
@@ -320,7 +320,7 @@ $$
|
||||
|
||||
观察递归树,容易发现其中存在重叠子问题,例如 $dp[1, 10]$ 等。而当物品较多、背包容量较大,尤其是相同重量的物品较多时,重叠子问题的数量将会大幅增多。
|
||||
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-18 0-1 背包的暴力搜索递归树 </p>
|
||||
|
||||
@@ -656,7 +656,7 @@ $$
|
||||
|
||||
图 14-19 展示了在记忆化递归中被剪掉的搜索分支。
|
||||
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-19 0-1 背包的记忆化搜索递归树 </p>
|
||||
|
||||
@@ -969,46 +969,46 @@ $$
|
||||
如图 14-20 所示,时间复杂度和空间复杂度都由数组 `dp` 大小决定,即 $O(n \times cap)$ 。
|
||||
|
||||
=== "<1>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<2>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<3>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<4>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<5>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<6>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<7>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<8>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<9>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<10>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<11>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<12>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<13>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<14>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-20 0-1 背包的动态规划过程 </p>
|
||||
|
||||
@@ -1024,22 +1024,22 @@ $$
|
||||
图 14-21 展示了在单个数组下从第 $i = 1$ 行转换至第 $i = 2$ 行的过程。请思考正序遍历和倒序遍历的区别。
|
||||
|
||||
=== "<1>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<2>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<3>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<4>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<5>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<6>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-21 0-1 背包的空间优化后的动态规划过程 </p>
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ comments: true
|
||||
|
||||
给定 $n$ 个物品,第 $i$ 个物品的重量为 $wgt[i-1]$、价值为 $val[i-1]$ ,和一个容量为 $cap$ 的背包。**每个物品可以重复选取**,问在不超过背包容量下能放入物品的最大价值。
|
||||
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-22 完全背包问题的示例数据 </p>
|
||||
|
||||
@@ -347,22 +347,22 @@ $$
|
||||
这个遍历顺序与 0-1 背包正好相反。请借助图 14-23 来理解两者的区别。
|
||||
|
||||
=== "<1>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<2>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<3>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<4>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<5>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<6>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-23 完全背包的空间优化后的动态规划过程 </p>
|
||||
|
||||
@@ -666,7 +666,7 @@ $$
|
||||
|
||||
给定 $n$ 种硬币,第 $i$ 种硬币的面值为 $coins[i - 1]$ ,目标金额为 $amt$ ,**每种硬币可以重复选取**,问能够凑出目标金额的最少硬币个数。如果无法凑出目标金额则返回 $-1$ 。
|
||||
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-24 零钱兑换问题的示例数据 </p>
|
||||
|
||||
@@ -1070,49 +1070,49 @@ $$
|
||||
图 14-25 展示了零钱兑换的动态规划过程,和完全背包非常相似。
|
||||
|
||||
=== "<1>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<2>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<3>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<4>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<5>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<6>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<7>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<8>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<9>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<10>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<11>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<12>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<13>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<14>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<15>"
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-25 零钱兑换问题的动态规划过程 </p>
|
||||
|
||||
@@ -1450,7 +1450,7 @@ $$
|
||||
|
||||
给定 $n$ 种硬币,第 $i$ 种硬币的面值为 $coins[i - 1]$ ,目标金额为 $amt$ ,每种硬币可以重复选取,**问在凑出目标金额的硬币组合数量**。
|
||||
|
||||

|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 图 14-26 零钱兑换问题 II 的示例数据 </p>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user