前言
算法中有个专题,动态规划,它十分的重要,大厂面试中或多或少有所涉及,来网易之前,刷了部分dp,这次正好再次梳理一遍,希望对你们有一点点帮助。
如果你已经懂了dp思路,或者已经掌握了常见的dp解法,可以直接跳过。
如果你还不了解,或者知道动态规划,但是还没有开始刷题的话,可能这篇文章适合你。
点击链接c/c++ linux技术分享扫码加群即可获得更多脑图和视频电子书资料
脑图👇
如果觉得看完文章有所收获的话,可以关注我一下哦
知乎:秃顶之路
b站:linux亦有归途
每天都会更新我们的公开课录播以及编程干货和大厂面经
或者直接点击链接
c/c++ linux服务器开发高级架构师
来课堂上跟我们讲师面对面交流
需要大厂面经跟学习大纲的小伙伴可以加群973961276获取
什么是动态规划
动态规划(Dynamic Programming),因此常用 DP 指代动态规划。动态规划,首先我们得清楚,它的概念是啥,它能解决什么问题,维基百科对它的解释👇
动态规划在寻找有很多重叠子问题的情况的最佳解时有效。它将问题重新组合成子问题,为了避免多次解决这些子问题,它们的结果都逐渐被计算并被储存,从简单的问题直到整个问题都被解决。因此,动态规划储存递归时的结果,因而不会在解决同样的问题时花费时间。动态规划只能应用于有最佳子结构的问题。最佳子结构的意思是局部最佳解能决定全域最佳解(对有些问题这个要求并不能完全满足,故有时需要引入一定的近似)。简单地说,问题能够分解成子问题来解决。
我稍微总结一下👇
- 将一个大的问题拆分成一个个子问题,我们把它称之为子结构。
- 每个最优解,也就是最优值均由[这些小规模子问题]推到而来。
- 更重要的就是利用
历史记录
,来避免我们重复的计算。
什么是重复计算,那怎么样可以利用历史记录来减少我们不必要的运算呢👇
我们拿斐波那契数列这题来看👇
如果我们按照这个递归的写法来看,那么它的过程如下👇
它会多次计算结果,这个符合动态规划的点,动态规划在寻找有很多重叠子问题的情况的最佳解时有效。而且对于这个问题而言,它可以继续去拆分,变成更小的子问题去解决,它也符合动态规划的预期。
那么这里只是举个例子,后续会将做题思路👇
动态规划解题三大步骤
对于初学者而言,需要短时间就掌握的话,我觉得挺难的,所以这里我推荐大家可以看看经典的动态规划👉背包九讲,点这里,看完它,或许对你有点帮助吧。
解题思路,三大步骤👇
- 状态定义
- 列出状态转移方程
- 初始化状态
-
- *
状态定义
- 我们需要借助数组来保存之前计算的结果,所以一般采用的就是数组来维护我们的结果,一般dp数组。
- dp数组的含义一定要明确,也就是说,dp[i]表达是啥意思,举个例子,dp[i]表达到达第i个阶梯时的方案数。
-
- *