动态规划
动态规划(dp)
递归与动态规划
动态规划是自底向上,递归树是自顶向下。
自顶向下:从一个规模较大的问题向下逐渐分解。如斐波那契问题,计算 f(20),逐步分解到f(1)、f(2),然后返回结果。
1 | int Fibonacci(size_t n){ |
自底向上:从最底下、最简单的问题开始往上推,也就是动态规划的思想,通过循环迭代得到结果。
1 | //利用动态规划计算斐波那契数列 |
动态规划法试图仅仅解决每个子问题一次,从而减少计算量:一旦某个给定子问题的解已经算出,则将其记忆化存储,以便下次需要同一个子问题解之时直接查表。
问题是否能用动态规划解决的是这些”小问题“会不会被被重复调用。
能用动态规划解决的问题
1、问题的答案依赖于问题的规模,也就是问题的所有答案构成了一个数列。
2、大规模问题的答案可以由小规模问题的答案递推得到,也就是的值可以由
中的个别求得。
应用动态规划
1、建立状态转移方程
2、缓存和复用以往结果
3、按顺序从小往大算
经典题型
连续子数组的最大和
问题陈述
输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。
要求时间复杂度为O(n)。
示例:
1 | 输入: nums = [-2,1,-3,4,-1,2,1,-5,4] |
思路分析
连续子数组,和最大,我们可以用dp的思想来解决此类问题,
走一遍nums数组元素,初始值为dp[0]=-2,从dp[1]开始判断,若之前和大于0,则加上;若小于0,则dp[i]=nums[i]。
并定义res存储最大值,res初始化为nums[0],并与每次的dp[i]比较取最大值。
通过上述分析:即知转移条件为:**dp[i]=nums[i] 当dp[i-1]<0; **
dp[i]=nums[i]+dp[i-1] 当dp[i-1]>0。
代码实现
1 | class Solution { |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 淋竹调!
评论