动态规划 Dynamic Programming
动态规划 (第1讲) UP主:正月点灯笼
动态规划 (第2讲) UP主:正月点灯笼
一、引入
(一) 题目一:斐波那契数列
![](https://i-blog.csdnimg.cn/blog_migrate/9883d78f88e45b548e754b42e074a43b.png)
上述方法算fib(7)时,会出现很多重叠子问题。时间复杂度为O(2^n)。
![](https://i-blog.csdnimg.cn/blog_migrate/1cb6b1bce31b4f84557bd6f198ffd305.png)
从前往后算,运用递归,时间复杂度减小为O(n)。
(二) 题目二
图中,表示8件工作:
横轴为时间点,灰色条表示这个工作占用的时间区间,红色字为这份工作可以挣得的钱。同一段时间内只能做一件工作。求,从0时刻到11时刻能赚得的最多的钱。
![](https://i-blog.csdnimg.cn/blog_migrate/94e0b9e7e3d53cd31a6b6dd3f79b0ad1.png)
![](https://i-blog.csdnimg.cn/blog_migrate/3099ca7b1eab2f51ffd57c4022bc8ae2.png)
1.OPT(i) 有前i个工作可选时,合理安排时间后可能能挣的最多的钱。option(可选项)
如,OPT(1)只做第一个工作,可能挣得最多的钱
OPT(2)有1,2两个工作可选时,合理安排时间可能挣得最多的钱
OPT(5)有1,2,3,4,5这五个工作可选时,合理安排时间后可能挣得最多的钱。
OPT(8) 有1,2,3,4,5,6,7,8这八个工作可选时,合理安排时间后可能挣得最多的钱。
2.Vi表示第i件事能赚的钱,value值。
3.prev(i)若选做第i件时,剩余事件中能做的最大序号
prev(8)为5,因为选做第8件后,6,7件都不能做,能做的事件的最大序号是5
![](https://i-blog.csdnimg.cn/blog_migrate/485ff2467b98b0a6e5bab294644c528f.png)
红色框,我们注意到了,这是重复子问题!所以我们可以从下往上算来减少复杂度,这种过程即“动态规划”。
![](https://i-blog.csdnimg.cn/blog_migrate/56cdd39cd1e4dd3eb1a6a8a65355b093.png)
(三)总结
1.什么是动态规划:
从结果出发一步步细化会出现重复子问题时,那我们从“下标小”往“下标大”做来避免重复子问题(像斐波那契数列一样从f[1]算到f[n])
2.利用递归
3.步骤与重点
step1.分为“选”与“不选”构造前后关系。
step2.涉及到递归则要有递归的两个部分:递归关系和递归出口。
二、两个题目
(一)题目一
给了一列数,找出互不相邻的几个数组成新的集合,求这个新的集合的这些数的和的最大值为多少。
![](https://i-blog.csdnimg.cn/blog_migrate/b8e9943c472766b9fa4a9f4af1afbad4.png)
![](https://i-blog.csdnimg.cn/blog_migrate/36f2134e767e7d77c67735132dbfc598.png)
![](https://i-blog.csdnimg.cn/blog_migrate/7f2c8fb0170a6cab29629e25ba583156.png)
(二)题目二
有一组数,是否存在其中几个数的和刚好等于S,返回TRUE或FALSE。