动态规划难?读完这篇还不理解那就不要请我吃鸡了

昨天同事说动态规划很难,我说不会啊,理解了就很简单,我同事表示不屑,觉得我在炫技。因而乎我问了一个工做六年的前同事,他竟然也以为高大上,而且表示接触过会动态规划的朋友,以为很牛逼。git

我了个天,表示震惊了,简直吓的我瑟瑟发抖发抖好么。既然如此,那我必定要让你们理解,让你们也牛逼牛逼。github

以题举例

以中国leetcode(力扣)的121道题《买卖股票的最佳时机》举例,题目以下:算法

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

若是你最多只容许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。

注意你不能在买入股票前卖出股票。

示例 1:

输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 由于卖出价格须要大于买入价格。

示例 2:

输入: [7,6,4,3,1]
输出: 0
解释: 在这种状况下, 没有交易完成, 因此最大利润为 0。
复制代码

首先说明一点,在这道题动态规划并不算是高效的算法,这道题即便是暴力法也能比动态规划法要快一些,但本文是为了讲动态规划才讲这道题的,而非为了这道题讲动态规划的。纯粹是这道题讲动态规划更简单。数组

不了解动态规划的朋友可能不知道,动态规划几乎都是存在套路的,步骤以下:bash

  1. 将问题拆解成单一问题制表
  2. 根据表中结果进行求解

第一步:将问题拆解成单一问题制表

这是动态规划的重中之重,拆的好坏基本决定你动态规划写的好坏,动态规划更是一种思想。分布式

这道题就很简单了,咱们能够把这个问题,先拆成单一问题,即若是我在这天买入,在哪天卖出最高? 咱们按题目中的示例 1举例,价格数组为[7,1,5,3,6,4]。性能

好比我在第一天买入,在哪天卖出最高呢?咱们能够获得这样一张表(不能交易标记X):spa

买入时间 买入价格 单天价格 7 1 5 3 6 4
-- -- 卖出时间 第一天 次日 第三天 第四天 第五天 第六天
第一天 7 获利程度 X -6 -2 -4 -1 -3

填表缘由以下:设计

  • 即由于你是第一天买入的,因此第一天不能交易,因此填X
  • 咱们第一天买入的,买入价格为7,次日值1,因此咱们卖出则赚了-6.
  • 咱们第一天买入的,买入价格为7,第三天值5,因此咱们卖出则赚了-2.
  • 咱们第一天买入的,买入价格为7,第四天值3,因此咱们卖出则赚了-4.
  • 咱们第一天买入的,买入价格为7,第五天值6,因此咱们卖出则赚了-1.
  • 咱们第一天买入的,买入价格为7,第六天值4,因此咱们卖出则赚了-3.

有人说这个不是暴力解法么?额,这道题的动态规划的制表过程确实有点像。code

那么根据以上规则,若是咱们是次日买入的话,这个表格是否是就是这样的。

买入时间 买入价格 单天价格 7 1 5 3 6 4
-- -- 卖出时间 第一天 次日 第三天 第四天 第五天 第六天
次日 1 获利程度 X X 4 2 5 3

那么我合并这两张表是否是就是这样的:

买入时间 买入价格 单天价格 7 1 5 3 6 4
-- -- 卖出时间 第一天 次日 第三天 第四天 第五天 第六天
第一天 7 获利程度 X -6 -2 -4 -1 -3
次日 1 获利程度 X X 4 2 5 3

那么咱们把这张表弄完整,即把第三天到第五天的买入,那是否是就是这样的。

买入时间 买入价格 单天价格 7 1 5 3 6 4
-- -- 卖出时间 第一天 次日 第三天 第四天 第五天 第六天
第一天 7 获利程度 X -6 -2 -4 -1 -3
次日 1 获利程度 X X 4 2 5 3
第三天 5 获利程度 X X X -2 1 -1
第四天 3 获利程度 X X X X 3 1
第五天 6 获利程度 X X X X X -2
第六天 4 获利程度 X X X X X X

由于第六天买了的话,已是最后一天了,因此没办法卖了,因此全是X。

第二步:根据表中结果进行求解

上一步,已经把若是是某天买的,天天的获利状况列了一遍,就是拆解成了单一问题。

那么看最大利润,很容易就能看出来了,就看那个数字最大就行了。

买入时间 买入价格 单天价格 7 1 5 3 6 4
-- -- 卖出时间 第一天 次日 第三天 第四天 第五天 第六天
第一天 7 获利程度 X -6 -2 -4 -1 -3
次日 1 获利程度 X X 4 2 5⃣️ 3
第三天 5 获利程度 X X X -2 1 -1
第四天 3 获利程度 X X X X 3 1
第五天 6 获利程度 X X X X X -2
第六天 4 获利程度 X X X X X X

没错emoji的5的就是,那么咱们只要简单的遍历一下这个表是否是就能把结果取出来了?嗯,对的

最后

但通常来讲动态规划的题目不是这么简单的,一般在制表的时候会涉及一个叠加问题,在根据表计算结果通常也不是简单的遍历就能完成的,但理解动态规划思想应该是没什么问题了。

我的认为动态规划虽然性能不强,可是能把问题变得很直观,让人更简单的解决问题。同时算法的杂合度不高,很方便使用分布式为问题的每一个单一问题进行求解。

本题代码:best-time-to-buy-and-sell-stock.js

相关文章
相关标签/搜索