来源地址:详解多种动态规划问题,看完必会动态规划
解题四大步:确定定义===》找初始值===》思考关系===》写代码解
例题一:青蛙跳台阶
问题:一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。
步骤1:确定定义
问总共有多少种跳法,就设置n个台阶级的跳法是dp[n]种
步骤2:找初始值
如果只有1级台阶,那么只有一种跳法,即只能跳一级台阶,dp[1] = 1;如果有两级台阶,可以先跳一级台阶,然后再跳一级台阶,或者直接跳两级台阶。一共有两种跳法,即dp[2] = 2;
那么初始值就设为dp[1] = 1, dp[2] = 2;
步骤3:思考关系
这一步可以用穷举分析法,然后发现规律,列出状态转移方程。
针对这一题,穷举分析如下:
为方便阅读,列了个表可视化
台阶数 | 跳法 | 跳法数 |
1 | 1 | 1 |
2 | 11,2 | 2 |
3 | 111,21,12 | 3 |
4 | 1111,121,211,22,112 | 5 |
5 | 11111,2111,221,1211,1121,1112,212,122 | 8 |
看着这个表,其实可以思考一下,将跳法理解为最后一步是跳1级还是跳2级,表可以这么改:
台阶数 | 最后一步跳1级的跳法 | 最后一步跳2级的跳法 | 跳法数 |
1 | 1 | - | 1 |
2 | 11 | 2 | 2 |
3 | 111,21 | 12 | 3 |
4 | 1111,121,211 | 22,112 | 5 |
5 | 11111,2111,221,1211,1121 | 1112,212,122 | 8 |
然后,可以观察出来这么一个规律,即f(n)=f(n-1)+f(n-2),这就是斐波那契数列咯!本题本质就是求斐波那契数列的变体解问题。
步骤4:写代码解
依据以上的关系等式写代码就好
class Solution:
def numWays(self, n):
dp = [0 for i in range(n+1)]
dp[1] = 1
dp[2] = 2
for i in range(3, n+1):
dp[i] = (dp[i-1] + dp[i-2]) % 1000000007
return dp[n]
例题二:连续子数组的最大和
输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。
【示例】
输入: nums = [-2,1,-3,4,-1,2,1,-5,4]。输出: 6。解释: 连续子数组 [4,-1,2,1] 和最大,为 6。
继续以上的四大步!
步骤1:确定定义
定义某个子数组的和最大值为max_num,动态规划是自底向上不断循环每一步的最优解来使得全局最优,全局最优解max_num已经有了,再设出每一步的局部最优解dp[i](i为循环这个数组的次数,值为每次循环中求得的最大数组)。
步骤2:找初始值
初始值很好设置,就将第一步的局部最优解和全局最优解设置为数组的第一个数字,即nums[0],毕竟要循环它嘛,后面根据循环不断变更这两个值就行。
步骤3:思考关系
如果在循环的过程中,子数组m加上下一个值n的和小于n,即m+n<n,那此时子数组m成为了n的累赘,这时就让n成为新的子数组,继续循环。 如果子数组m加上下一个值n的和大于n,即m+n>n,就将n加到m中,新的子数组就是m+n,即使n的值可能为负数,因为后面可能会有更大的正数,如果遇到n为负数就停滞不前了,那后面如果存在连续很多个都是正数,就得不到想要的最大值了(其实这里我暂时还没完全理解到,如果有大佬看到,希望可以通俗易懂的讲解一下,万分感谢!)。
然后就可以构造出关系式了,就是每次循环中子数组的和应该怎么取:
dp[i] = max(dp[i-1] + nums[i], nums[i])
步骤四:写代码解
class Solution:
def max_sumsubarray(self, nums):
dp = [0 for i in range(len(nums))]
dp[0] = nums[0]
max_num = nums[0]
for i in range(1, len(nums)):
dp[i] = max(dp[i-1] + nums[i], nums[i])
max_num = max(max_num, dp[i])
return max_num
if __name__ == '__main__':
solution = Solution()
nums = [-2,1,-3,4,-1,2,1,-5,4]
num = solution.max_sumsubarray(nums)
print(num)
我下来再理解一下吧,脑子不太灵光,哈哈哈,这个理解透了再去看看其他更难的动态规划题。