This commit is contained in:
krahets
2023-08-19 22:07:27 +08:00
parent 71c7786f51
commit 2e27ad1680
99 changed files with 283 additions and 283 deletions
@@ -3,7 +3,7 @@ comments: true
status: new
---
# 14.1.   初探动态规划
# 14.1   初探动态规划
「动态规划 Dynamic Programming」是一个重要的算法范式,它将一个问题分解为一系列更小的子问题,并通过存储子问题的解来避免重复计算,从而大幅提升时间效率。
@@ -360,7 +360,7 @@ status: new
}
```
## 14.1.1.   方法一:暴力搜索
## 14.1.1   方法一:暴力搜索
回溯算法通常并不显式地对问题进行拆解,而是将问题看作一系列决策步骤,通过试探和剪枝,搜索所有可能的解。
@@ -615,7 +615,7 @@ $$
以此类推,子问题中包含更小的重叠子问题,子子孙孙无穷尽也。绝大部分计算资源都浪费在这些重叠的问题上。
## 14.1.2.   方法二:记忆化搜索
## 14.1.2   方法二:记忆化搜索
为了提升算法效率,**我们希望所有的重叠子问题都只被计算一次**。为此,我们声明一个数组 `mem` 来记录每个子问题的解,并在搜索过程中这样做:
@@ -923,7 +923,7 @@ $$
<p align="center"> 图:记忆化搜索对应递归树 </p>
## 14.1.3. &nbsp; 方法三:动态规划
## 14.1.3 &nbsp; 方法三:动态规划
**记忆化搜索是一种“从顶至底”的方法**:我们从原问题(根节点)开始,递归地将较大子问题分解为较小子问题,直至解已知的最小子问题(叶节点)。之后,通过回溯将子问题的解逐层收集,构建出原问题的解。
@@ -1167,7 +1167,7 @@ $$
<p align="center"> 图:爬楼梯的动态规划过程 </p>
## 14.1.4. &nbsp; 状态压缩
## 14.1.4 &nbsp; 状态压缩
细心的你可能发现,**由于 $dp[i]$ 只与 $dp[i-1]$ 和 $dp[i-2]$ 有关,因此我们无需使用一个数组 `dp` 来存储所有子问题的解**,而只需两个变量滚动前进即可。