分享

分享动态规划学习种的一点感觉:

首先,官方一点的概念:我们把要解决的一个大问题转换成若干个规模较小的同类型问题,当我们求解出这些小问题的答案,大问题便不攻自破。同时,在求解这些小问题的过程中,我们把需要重复计算的答案记录下来放在数组中,下次如果遇到同样的小问题需要计算,便直接查询出结果。这就是动态规划。

其中重复的过程可以用一个状态转移方程来表示,所以最重要的是求状态转移方程。语雀里面有学长发过一个关于动态规划的文章,我就抛砖引玉吧。。。

先看几道例题,从其中体会下这个过程,

①.爬楼梯

分享20.4.26

  • 上 1 阶台阶:有 1 种方式

  • 上 2 阶台阶:有 1+1 和 2 两种方式

  • 上 3 阶台阶:我们只能从第 2 阶或者第 1 阶 到达第 3 阶,所以到达第 3 阶的方法总数就是到第 1 阶和第 2 阶的方法数之和。

  • 上 n 阶台阶:我们只能从第 n-1 阶或者第 n-2 阶 到达第 n 阶,所以到达第 n 阶的方法总数就是到第 n-1 阶和第 n-2 阶的方法数之和。

所以:dp[n]=dp[n-1]+dp[n-2]

②.最大子序和

分享20.4.26

动态规划第一步:定义状态。对于本题如何定义状态?我们分析题目,一个连续子数组一定要以一个数作为结尾,那是不是可以定义dp[i] 表示以 nums[i] 结尾的连续子数组的最大和。为啥要这样定义?如果要得到dp[i],那么nums[i]一定会被选取。并且 dp[i] 所表示的连续子序列与 dp[i-1] 所表示的连续子序列很可能就差一个 nums[i],当然这是在dp[i-1]大于0的情况下

dp[i]=max(nums[i], dp[i−1]+nums[i])
分享20.4.26

③.

分享20.4.26

首先我们分析题目,要找的是最长上升子序列(Longest Increasing Subsequence,LIS)。因为题目中没有要求连续,所以**LIS可能是连续的,也可能是非连续的。**同时,LIS符合可以从其子问题的最优解来进行构建的条件。所以我们可以尝试用动态规划来进行求解。首先我们定义状态:dp[i] 表示以nums[i]结尾的最长上升子序列的长度。

dp[i] = max(dp[j]+1,dp[k]+1,dp[p]+1,…)

图解:

分享20.4.26

以后有空在补充吧。。。(含泪告别)

相关文章: