3030
3131通过公式 $f(n) = f(n - 2) + f(n - 1)$,我们可以将原问题 $f(n)$ 递归地划分为 $f(n - 2)$ 和 $f(n - 1)$ 这两个子问题。其对应的递归过程如下图所示:
3232
33- ![ ] ( ../../images/20230307164107.png )
33+ ![ 斐波那契数列的重复计算项 ] ( ../../images/20230307164107.png )
3434
3535从图中可以看出:如果使用传统递归算法计算 $f(5)$,需要先计算 $f(3)$ 和 $f(4)$,而在计算 $f(4)$ 时还需要计算 $f(3)$,这样 $f(3)$ 就进行了多次计算。同理 $f(0)$、$f(1)$、$f(2)$ 都进行了多次计算,从而导致了重复计算问题。
3636
@@ -83,13 +83,13 @@ class Solution:
8383
8484也就是说,如果原问题的最优解包含子问题的最优解,则说明该问题满足最优子结构性质。
8585
86- ![ ] ( ../../images/20220511175042 .png )
86+ ![ 最优子结构性质 ] ( ../../images/20240513163310 .png )
8787
8888### 2.2 重叠子问题性质
8989
9090> ** 重叠子问题性质** :指的是在求解子问题的过程中,有大量的子问题是重复的,一个子问题在下一阶段的决策中可能会被多次用到。如果有大量重复的子问题,那么只需要对其求解一次,然后用表格将结果存储下来,以后使用时可以直接查询,不需要再次求解。
9191
92- ![ ] ( ../../images/20230307175804 .png )
92+ ![ 重叠子问题性质 ] ( ../../images/20230307164107 .png )
9393
9494之前我们提到的「斐波那契数列」例子中,$f(0)$、$f(1)$、$f(2)$、$f(3)$ 都进行了多次重复计算。动态规划算法利用了子问题重叠的性质,在第一次计算 $f(0)$、$f(1)$、$f(2)$、$f(3)$ 时就将其结果存入表格,当再次使用时可以直接查询,无需再次求解,从而提升效率。
9595
@@ -103,15 +103,15 @@ class Solution:
103103
104104而如果一个问题具有「后效性」,则可能需要先将其转化或者逆向求解来消除后效性,然后才可以使用动态规划算法。
105105
106- ![ ] ( ../../images/202303072158573 .png )
106+ ![ 无后效性 ] ( ../../images/20240514110127 .png )
107107
108108## 3. 动态规划的基本思路
109109
110110如下图所示,我们在使用动态规划方法解决某些最优化问题时,可以将解决问题的过程按照一定顺序(时间顺序、空间顺序或其他顺序)分解为若干个相互联系的「阶段」。然后按照顺序对每一个阶段做出「决策」,这个决策既决定了本阶段的效益,也决定了下一阶段的初始状态。依次做完每个阶段的决策之后,就得到了一个整个问题的决策序列。
111111
112112这样就将一个原问题分解为了一系列的子问题,再通过逐步求解从而获得最终结果。
113113
114- ![ ] ( ../../images/20220720180135 .png )
114+ ![ 动态规划方法 ] ( ../../images/20240514110154 .png )
115115
116116这种前后关联、具有链状结构的多阶段进行决策的问题也叫做「多阶段决策问题」。
117117
@@ -396,4 +396,4 @@ class Solution:
396396- 【书籍】算法训练营 陈小玉 著
397397- 【书籍】趣学算法 陈小玉 著
398398- 【书籍】算法竞赛进阶指南 - 李煜东 著
399- - 【书籍】ACM-ICPC 程序设计系列 - 算法设计与实现 - 陈宇 吴昊 主编
399+ - 【书籍】ACM-ICPC 程序设计系列 - 算法设计与实现 - 陈宇 吴昊 主编
0 commit comments