總結 動態規劃概述

2021-08-07 11:04:18 字數 4623 閱讀 7327

舉例2 - copy paste參考

動態規劃,就實際的作用而言,把多階段過程轉化為一系列單階段問題,利用各階段之間的關係,逐個求解。

【核心觀點】動態規劃 = 階段劃分 + 階段之間的關係

本文主要通過一種嘗試試探的方法,去探索動態規劃階段劃分的角度。

需要注意

(1)【階段劃分的角度】,決定了你理解事物的難易程度,以及後面階段間關係的複雜度。(後面我們會通過乙個例子( 探索法展示 )進行分析)

(2)【階段劃分角度的多樣性】我們觀察乙個事物的時候,不只有乙個角度去觀察,而是有很多角度,不同的角度造成了不同的解決問題的方式。我們需要承認,求解問題時,是可以有多種階段劃分的辦法的。(後面將展示一些階段劃分的探索以及小技巧)

(3)【重新選角度劃分階段】當你選擇了某種階段劃分的角度,出現如下問題時,你可能需要換乙個角度來重新劃分階段:1.劃分的角度難以理解,難以繼續往下思考,情況數**增長;2.劃分之後,各階段的角度混雜,沒有區域性關聯性(只和相鄰的幾個階段相關聯)。

主要通過乙個列子來說明這其中包含的思想。

輸入乙個整形陣列,陣列裡有正數也有負數。(設陣列中元素數目為 n)

陣列中連續的乙個或多個整數組成乙個子陣列,每個子陣列都有乙個和。

求所有子陣列的和的最大值。要求時間複雜度為o(n)

例如輸入的陣列為1, -2, 3, 10, -4, 7, 2, -5,和最大的子陣列為3, 10, -4, 7, 2,

因此輸出為該子陣列的和18。

理論上可用動態規劃的特徵

最優子結構】能劃分階段而且大問題的最優解可以由小問題推出來。

無後效性】某階段的狀態一旦確定,則此後過程的演變不再受此前各種狀態及決策的影響

簡單的說,就是當前的狀態是此前歷史的乙個完整總結此前的歷史只能通過當前的狀態去影響過程未來的演變,「未來與過去無關」

具體地說,如果乙個問題被劃分各個階段之後,階段 i 中的狀態只能由階段 i-1 中(或多個有限歷史階段)的狀態通過狀態轉移方程得來,與其它狀態沒有關係,特別是與未發生的狀態沒有關係。

ps:遞推本身是無後效性的反映。(如:f(

i)=g

(f(i

−1))

,滿足無後效性,及最優子結構

一般是憑經驗,下面列舉情況:

階段】動態規劃的題都是可以分出階段的。

環狀:不適用(有後效性)乙個問題有環狀結構一般就不能用dp。比如求圖的最短路。如果是鏈狀結構就可以用dp,例如有向無環圖的最短路。(其實把dp的狀態關係畫出來就是乙個dag)

時刻牢記 我們尋找的遞推,應該具有的特徵:

最優子結構 + 無後效性

劃分階段的角度

定義階段】將前 k 個元素 處理的找到的最大值,當作乙個階段,用 f (k) 。

尋找階段間的關係】當我們定義了階段之後,接下來便是尋找階段間的關係。基於兩點來判斷:1.是否是最優子結構;2.是否具有無後效性。

最優】根據我們對於階段的定義,我們能夠確定:f ( n ) 的結果就是想要的結果。

無後效性:排除】按照我們的階段劃分,發現不具有無後效性的特點。 f(k) 不僅依賴於 f(k-1),因為 可能 f( k -1 ) = f ( k - 2) = … (因為可能在前k個元素中,前2個元素構成了最大的值),且這種依賴是不確定的,你不知道依賴前面幾個。 —>所以這種做法是不合適的。

前面一種試探的方法失敗了,我們只得重新尋找劃分階段的角度。

借鑑上一次失敗的教訓,沒有滿足無後效性。我們這次需要尋找一種,具有無後效性的方式。

在這次求解之前,提出如下幾個問題

(1)【一定要得到直接的結果? no】我們假設找到了乙個函式 f 能夠很好的劃分階段,那麼 f(n)是否直接就是需要的答案呢?即f ( n ) 就對應著最終所求最大值

對於上面的問題,是否定的。那麼做太死板,把問題的空間限定的很死。而且,一些間接的答案也是可以匯出最終的答案的。(如:接下來要提的這種角度)

(2)【如何保證無後效性的存在?】連續子陣列意味著,如果某個子陣列中末位為 k ,而 k -1 不在陣列中,那麼 k -1 之前的元素 也一定不在陣列中。元素 k-1的存在與否很好的告知了 元素 k 過去的歷史

(1)間接逼近目標(將問題歸結為更容易操作的其他問題),下面是一些例項:

leetcode - 303. range sum query - immutable 【動態規劃 + 間接逼近目標 + 區間計算 +刻度 + 距離計算方式 】

劃分角度

新劃分】我們規定以 第 k個元素結尾的子陣列和最大為 f (k).

劃分匯出的關係

(1)f(k-1) < 0 , 對 f (k)貢獻為負,捨棄,於是f(k) = data[k],其中data[k]表示陣列中第k個元素。

(2)f(k-1) > 0,對 f( k )貢獻為正,納入,於是f(k) = f (k-1) + data[k]。 因為 f (k-1) 保證了第k-1個元素一定在子陣列中,所以加入data[k]之後,依舊是連續的,符合題目要求

(間接)得到答案從 f(i)中選擇最大值。(1 <= i <= n)

核心**

result = a[1]

sum = a[1]

for i: 2

to length[a]

ifsum > 0

sum += a[i]

else

sum = a[i]

ifsum > result

result = sum

return

result

劃分角度 : 依賴性】考慮現在與過去的階段相關性,各階段間部分相關還是全部相關有沒有一種劃分方法,能夠將相關性變為部分相關,從而降低計算代價

某個階段的狀態數量】在動態規劃的過程中,某個階段的狀態是乙個還是多個

多個的情況,需要設定多維陣列來進行儲存。(比如,該題目中網友的做法d[i][j][k])。但這無疑也增加了空間複雜度。

1個的情況,只需要設定1維陣列即可(比如,下面題目我的設計,d[i]),此處通過乙個函式將題目的需求以及 網友的那種做法進行了壓縮儲存,能夠服務於求解的目的,同時又具有較好的空間複雜度。

原題目**

大概意思是你有3中操作可以做:

在鍵盤上敲乙個字元

複製一段現有字串

貼上剪下板上的字元到最後

請問,最少需要多少次操作才能生成一給定的字串,字串長度是100。

d[i]: 表示得到前 i 個字元,需要的最少時間。

d[i+1]: 選最小,包括:d[i]+1,d[j] +1(長度為i+1-j的字串存在 && 與第j+1到i+1的字元匹配),其中j < i。

求連續子陣列的最大和

如何判斷乙個問題是否可用動態規劃演算法求解?

動態規劃總結

華電北風吹 天津大學認知計算與應用重點實驗室 日期 2015 12 7 近期學了幾個動態規劃正好總結一下。裡面不涉及具體問題的具體解法,有問題可以參看我的具體型別的講解部落格。目前所見動態規劃可以劃分為兩類 鏈式和樹形。而且這兩類中的每個節點都是乙個完整的狀態集合。一 鏈式動態規劃 鏈式動態規劃的題...

動態規劃 總結

動態規劃是解決多階段決策問題的一種方法。如果一類問題的求解過程可以分為若干個互相聯絡的階段,在每乙個階段都需作出決策,並影響到下乙個階段的決策,從而確定了乙個過程的活動路線,則稱它為多階段決策問題。思想 在做每一步決策時,列出各種可能的區域性,解依據某種判定條件,捨棄那些肯定不能得到最優解的區域性解...

動態規劃總結

一 知識點整理 一 動態規劃是解決多階段策略問題的一種方法,運用最優性原理,排除重複計算,用空間換時間的演算法。二 動態規劃適用的題目型別有以下幾個特點 1.問題具有多階段的決策 2.每個階段對應乙個狀態 狀態變數 3.每個階段有乙個決策 不同的決策導致下乙個階段不同的狀態 4.每個階段的最優解可以...