|
|
@ -2,7 +2,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
「动态规划 Dynamic Programming」是一种用于解决复杂问题的优化算法,它把一个问题分解为一系列更小的子问题,并把子问题的解存储起来以供后续使用,从而避免了重复计算,提升了解题效率。
|
|
|
|
「动态规划 Dynamic Programming」是一种用于解决复杂问题的优化算法,它把一个问题分解为一系列更小的子问题,并把子问题的解存储起来以供后续使用,从而避免了重复计算,提升了解题效率。
|
|
|
|
|
|
|
|
|
|
|
|
在本节中,我们先从一个动态规划经典例题入手,了解动态规划是如何高效地求解问题的。
|
|
|
|
在本节中,我们先从一个动态规划的经典例题入手,先给出它的暴力回溯解法,观察其中包含的重叠子问题,再一步步导出更高效的动态规划解法。
|
|
|
|
|
|
|
|
|
|
|
|
!!! question "爬楼梯"
|
|
|
|
!!! question "爬楼梯"
|
|
|
|
|
|
|
|
|
|
|
@ -471,4 +471,8 @@ $$
|
|
|
|
|
|
|
|
|
|
|
|
**我们将这种空间优化技巧称为「状态压缩」**。在许多动态规划问题中,当前状态仅与前面有限个状态有关,不必保存所有的历史状态,这时我们可以应用状态压缩,只保留必要的状态,通过“降维”来节省内存空间。
|
|
|
|
**我们将这种空间优化技巧称为「状态压缩」**。在许多动态规划问题中,当前状态仅与前面有限个状态有关,不必保存所有的历史状态,这时我们可以应用状态压缩,只保留必要的状态,通过“降维”来节省内存空间。
|
|
|
|
|
|
|
|
|
|
|
|
实际上,所有动态规划问题都可以使用回溯算法解决,因为回溯算法本质上就是穷举,它能够遍历决策树的所有可能的状态,并从中记录需要的解。
|
|
|
|
总的看来,子问题分解是一种通用的算法思路,在分治算法、动态规划、回溯算法中各有特点:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 分治算法将原问题划分为几个独立的子问题,然后递归解决子问题,最后合并子问题的解得到原问题的解。例如,归并排序将长数组不断划分为两个短子数组,再将排序好的子数组合并为排序好的长数组。
|
|
|
|
|
|
|
|
- 动态规划也是将原问题分解为多个子问题,但与分治算法的主要区别是,**动态规划中的子问题往往不是相互独立的**,原问题的解依赖于子问题的解,而子问题的解又依赖于更小的子问题的解。因此,动态规划通常会引入记忆化,保存已经解决的子问题的解,避免重复计算。
|
|
|
|
|
|
|
|
- 回溯算法在尝试和回退中穷举所有可能的解,并通过剪枝避免不必要的搜索分支。原问题的解由一系列决策步骤构成,我们可以将每个决策步骤之后的剩余问题看作为一个子问题。
|
|
|
|