当前位置:   article > 正文

两个入门级例题了解动态规划(自用版,python)

两个入门级例题了解动态规划(自用版,python)

来源地址:详解多种动态规划问题,看完必会动态规划

解题四大步:确定定义===》找初始值===》思考关系===》写代码解

例题一:青蛙跳台阶

问题:一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。
步骤1:确定定义

问总共有多少种跳法,就设置n个台阶级的跳法是dp[n]种

步骤2:找初始值

如果只有1级台阶,那么只有一种跳法,即只能跳一级台阶,dp[1] = 1;如果有两级台阶,可以先跳一级台阶,然后再跳一级台阶,或者直接跳两级台阶。一共有两种跳法,即dp[2] = 2;

那么初始值就设为dp[1] = 1, dp[2] = 2;

步骤3:思考关系

这一步可以用穷举分析法,然后发现规律,列出状态转移方程。

针对这一题,穷举分析如下:

为方便阅读,列了个表可视化

台阶数跳法跳法数
111
211,22
3111,21,123
41111,121,211,22,1125
511111,2111,221,1211,1121,1112,212,1228

看着这个表,其实可以思考一下,将跳法理解为最后一步是跳1级还是跳2级,表可以这么改:

台阶数最后一步跳1级的跳法最后一步跳2级的跳法跳法数
11-1
21122
3111,21123
41111,121,21122,1125
511111,2111,221,1211,11211112,212,1228

然后,可以观察出来这么一个规律,即f(n)=f(n-1)+f(n-2),这就是斐波那契数列咯!本题本质就是求斐波那契数列的变体解问题。

步骤4:写代码解

依据以上的关系等式写代码就好

  1. class Solution:
  2. def numWays(self, n):
  3. dp = [0 for i in range(n+1)]
  4. dp[1] = 1
  5. dp[2] = 2
  6. for i in range(3, n+1):
  7. dp[i] = (dp[i-1] + dp[i-2]) % 1000000007
  8. 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])

步骤四:写代码解
  1. class Solution:
  2. def max_sumsubarray(self, nums):
  3. dp = [0 for i in range(len(nums))]
  4. dp[0] = nums[0]
  5. max_num = nums[0]
  6. for i in range(1, len(nums)):
  7. dp[i] = max(dp[i-1] + nums[i], nums[i])
  8. max_num = max(max_num, dp[i])
  9. return max_num
  10. if __name__ == '__main__':
  11. solution = Solution()
  12. nums = [-2,1,-3,4,-1,2,1,-5,4]
  13. num = solution.max_sumsubarray(nums)
  14. print(num)

我下来再理解一下吧,脑子不太灵光,哈哈哈,这个理解透了再去看看其他更难的动态规划题。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/1017845
推荐阅读
相关标签
  

闽ICP备14008679号