这几个算法,本质上,就是“将一个复杂的问题,分解成各种子问题,同时寻找它的重复性”
差别仅仅在于,一些小的细节的问题
(1)动态规划和递归或者分治,没有根本上的区别(关键看有无最优的子结构)
如果没有最优子结构,就需要把所有子问题都要计算一遍,同时把计算的结果合并在一起,传统意义上就称为分治
(2)共性:找到重复子问题
(3)差异性:动态规划具有最优子结构、中途可以淘汰次优解(必须淘汰次优解,降低复杂度,把问题求解从指数级别降到多项式级别)
人肉递归是比较低效的,而且个人会觉得很累,因为人脑的记忆很多时候其实并不准确。
在计算的时候经常可能会容易出错。
递归多了,比如下象棋,递归到第三层第四层的话,有时候不记得这个棋盘,上一层是走成什么样了。
因此,人脑记忆准确性很差。
用计算机来解决问题,最关键就是找到最近的最简的方法,将其分解成可重复解决的问题
可能有人会问,假设这个题目就没有可重复的问题,有没有这种情况,实际上,有的,这种情况的话可能就是它的复杂度,本身就是客观存在的,不能用循环或者递归来解决,如果问题本身很复杂的话,一般来说代码量就会有比如一百行、两百行
这样的题目一般不会出现在面试里
解决类似于有重复子问题的问题的时候,大家记得高中时候学的数学归纳法,一定要养成数学归纳法的习惯
就是说,先把基础的条件,即当 n=1,n=2 时,它的最基本条件是什么想明白,然后再解决,当如果 n 成立的话,怎么推到 n+1
举一个比喻,就是说一串炮竹,要保证它能够爆炸,那么,要证明第一点,可以点燃第二个炮竹,第二点是当前一个炮竹爆炸的时候,后面的一个炮竹肯定会爆炸,所以,整个一串鞭炮能够确保全部爆炸
本质:寻找重复性 -> 计算机指令集
“Simplifying a complicated problem by breaking it down into simpler sub-problems”(in a recursive manner)
“将一个复杂的问题,分解成简单的子问题”(用一种递归的方式)
动态规划(Dynamic Programming,DP),一种解决棘手问题的方法,先将大问题分解小问题,然后着手解决这些小问题,获取小问题的最优解,进而逐步解决大问题
分而治之(Divide & Conquer) + 最优子结构(Optimal substructure)
动态规划,本质上要解决的问题,就是一个递归问题或者分治问题,动态规划(DP)与分治(DC)是有内在联系的
动态规划与普通的递归、分治稍微有一点不同,即动态规划拥有所谓的最优子结构,也就是该动态规划的实际组成
一般来说,动态规划的问题,主要是求出最优解,或者求出一个最大值,或者求出一个最少的方式。
动态规划问题存在最优子结构,中间每一步不需要把所有的状态保存下来,只需要存最优的状态。同时,也需要证明每一步存着相当于最优的值,最后,能够推导出一个全局最优的值。
因此,引入了两个,第一个是所谓的缓存,或者状态的存储数组,第二个就是在每一步把次优的状态淘汰掉,只保留这一步里面最优的或者较优的一些状态推导出最后的全局最优
动态规划某种意义上说,在于找到状态转移方程,例如背包问题,而状态转移方程,就是找到最优解,相当于递归。
斐波那契数列,不淘汰次优解,傻递归或者傻分治,复杂度指数增长,采用动态规划,可以将复杂度指数增长变为多项式级别
极客时间《数据结构与算法之美》40 | 初识动态规划:如何巧妙解决“双十一”购物时的凑单问题?
极客时间《数据结构与算法之美》41 | 动态规划理论:一篇文章带你彻底搞懂最优子结构、无后效性和重复子问题