本篇阅读时间可能较长,推荐配合以下歌曲食用 ↓
由于考虑到我太菜了,又找了一个模板题来做,看看能不能有所领悟Orz
贴一个维基百科对动态规划的介绍
dynamic programming is a method for solving a complex problem by breaking it down into a collection of simpler subproblems.
初中英语级别,我觉得不用翻译都能看懂(其实应该翻译作动态决策比较好)
动态规划是一种通过拆分问题,定义问题和状态之间的关系,从而让问题能以递推或分治来解决
重点是拆分问题,如何拆分问题 是动态规划解决问题的核心
状态 和 状态转移方程 就是如何拆分问题 的核心,换句话说就是大事化小,小事化了,只不过在DP里面是反过来,从小到大
这里借用RXZ鸽鸽(雾)的段对解决DP问题的思路
【DP三连】
设计DP算法,往往可以遵循DP三连:
我是谁? ——设计状态,表示局面
我从哪里来?
我要到哪里去? ——设计转移设计状态是DP的基础。接下来的设计转移,有两种方式:一种是考虑我从哪里来(本文之前提到的两个例子,都是在考虑“我从哪里来”);另一种是考虑我到哪里去,这常见于求出f(x)之后,更新能从x走到的一些解。这种DP也是不少的,我们以后会遇到。
总而言之,“我从哪里来”和“我要到哪里去”只需要考虑清楚其中一个,就能设计出状态转移方程,从而写代码求解问题。前者又称pull型的转移,后者又称push型的转移。(这两个词是 @阮止雨 妹妹告诉我的,不知道源出处在哪)
贴个例题(从RXZ鸽鸽的知乎回答下借来的)
例题:最长上升子序列(LIS)
最长上升子序列(LIS)问题:给定长度为n的序列a,从a中抽取出一个子序列,这个子序列需要单调递增。问最长的上升子序列(LIS)的长度。
e.g. 1,5,3,4,6,9,7,8的LIS为1,3,4,6,7,8,长度为6。
遵循上面的DP三连,我们开始解决问题
第一步
我是谁?
这里的” 我 “很明显就是状态
我们设 Long(N)为 以 X 结尾的上升子序列 , K为这个数列中的最后一项的值
很明显,我们需要的答案就是
第二步
我从哪里来?
那么Long(X 1) 就可以+ 1,answer就可以等于Long(X 1)
由此可得DP方程
然后上代码
1 |
|
其实这篇的核心内容都是从RXZ鸽鸽的知乎回答上搬下来的,但是通过自己写一遍,总结一遍,思路也稍稍拓宽了一点
就算身在弱省我也菜死了,不知道下半年能不能水个省一QAQ