動態規劃難?讀完這篇還不理解那就不要請我吃雞了

昨天同事說動態規劃很難,我說不會啊,理解了就很簡單,我同事表示不屑,覺得我在炫技。因而乎我問了一個工做六年的前同事,他竟然也以爲高大上,而且表示接觸過會動態規劃的朋友,以爲很牛逼。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

相關文章
相關標籤/搜索