动态规划问题(Dynamic Programming)
动态规划DP
最近在做剑指算法题的时候遇到一个动态规划问题,遇到了一点麻烦,题目是连续子数组的最大和。然后发现之前没有系统学习过DP的问题,于是准备写个笔记记一下摸索动态规划的过程,以下内容大多是在学习过程中参考博客或者资料的内容再加上我自己的理解。
动态规划可以简单理解为将一个问题拆成几个子问题,分别求解这些子问题,即可推断出大问题的解。
动态规划三要素:最优子结构,边界和状态转移函数
【最优子结构】大问题的最优解可由子问题的最优解推出,最优子结构性质。
【边界】问题最小子集的解(初始范围)。有点类似递归的基例,在Fibonacci问题的时候可以用动态规划划分边界,也可以用递归定义基例,在这里都是F(1)和F(2)。我是这么理解的。
【状态转移函数】状态转移函数是指从一个阶段向另一个阶段的具体形式,描述的是两个相邻子问题直接的关系(递推式)。
重叠子问题,对每个子问题只计算一次,然后将其保存,每一次需要上一个子问题解时调用,只需要O(1)的时间复杂度。
判断是否可以利用动态规划求解,第一个是判断是否存在重叠子问题。
连续子数组的最大和问题
剑指的问题是这样的:例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和。
一开始用最笨的方法用很多分支结构枚举了可能出现的情况,这样代码量相当大还显得极其笨拙,在摸索了一下动态规划之后,终于写出改良版的代码:
class Solution:
def FindGreatestSumOfSubArray(self, array):
# write code here
d = [i for i in array] #创建数组以保存子问题的解
for i in range(1, len(array)):
d[i] = max(array[i], array[i]+d[i-1])
return max(d)
看到讨论区的大佬还有几种别的解法,继续摸索!