狀態與狀態轉移方程

2021-09-22 18:43:15 字數 1449 閱讀 5944

在之前的兩節中已經討論了兩類較為經典的動態規劃問題的解法,本節將對兩種演算法進行總結,並**解動態規劃問題的統一思路。

回顧兩種經典問題的演算法模式,都先定義了乙個數字量,如最長遞增子串行中用dp[i]表示以序列中第i個數字結尾的最長遞增子串行長度和最長公共子串行中用dp[i][j]表示的兩個字串中前 i、j 個字元的最長公共子串行,就是通過對這兩個數字量的不斷求解最終得到答案的。這個數字量就被稱為狀態。

狀態是描述問題當前狀況的乙個數字量。首先,它是數字的,是可以被抽象出來儲存在記憶體中的。其次,它可以完全的表示乙個狀態的特徵,而不需要其他任何的輔助資訊。最後,也是狀態最重要的特點,狀態間的轉移完全依賴於各個狀態本身,如最長遞增子串行中,dp[x]的值由dp[i](i < x)的值確定。若在分析動態規劃問題的時候能夠找到這樣乙個符合以上所有條件的狀態,那麼多半這個問題是可以被正確解出的。這就是為什麼人們常說,做 dp 題的關鍵,就是尋找乙個好的狀態。

將注意力放到狀態的遞推過程中來,由乙個或多個老的狀態得出乙個新的狀態的過程,被稱為狀態的轉移。如最長公共子串行中,通過dp[i - 1][j - 1]dp[i][j - 1]dp[i-1][j]的值轉移得出dp[i][j]的值就是該問題中的狀態轉移。而之前所說的數字量間的遞推關係就被稱為狀態的轉移規則,也被稱為狀態轉移方程,確定狀態的轉移規則即確定了怎樣由前序狀態遞推求出後續狀態。如最長非遞增子串行問題中的狀態轉移方程為:

最後來討論動態規劃問題的求解中相關時間複雜度的估計。

以最長公共子串行為例,設兩個字串長度分別為 l1 和 l2,則共有 l1*l2個狀態要求解,為了求解每個狀態,按照相應字元是否相等選取dp[i - 1][j -1] + 1或者max(dp[i][j - 1],dp[i - 1][j])dp[i][j]的值,即狀態轉移過程中每個狀態的得出僅需要o(1)的時間複雜度,所以總的時間複雜度為o(l1 * l2 * 1)

通過以上分析,同樣也可以判斷出求解最長遞增子串行問題的時間複雜度構成:假設原數列長度為 n,則狀態數量為 dp[n],狀態轉移過程中每個狀態的得出複雜度平均為 o(n),所以其總的時間複雜度為o(n*n)

總結一下,動態規劃問題的時間複雜度由兩部分組成:狀態數量和狀態轉移複雜度,往往程式總的複雜度為它們的乘積。所以說,選擇乙個好的狀態不僅關係到程式的正確性,同時對演算法的複雜度也有較大的影響,它在動態規劃問題中有著舉足輕重的地位。相對來說空間複雜度則沒那麼容易確定,可能需要額外的記憶體空間來輔助狀態的確定和轉移,也可能通過某種記憶體的復用提高記憶體的利用率。

動態規劃 狀態轉移方程練習

1.給定乙個陣列penny表示可用的零錢都有哪些面值,再給定乙個整數n表示penny的長度,再給定乙個整數m表示需要換零錢的整錢面值,輸出換錢的方案有幾種。樣例 1,2,4 3,3 返回 2 這是乙個比較簡單的動態規劃問題,dp為狀態陣列,只使用1的時候有一種方法 3 1 1 1 使用1 2的時候有...

01揹包的狀態轉移方程

這類問題算是再普通不過了,但是,我忘了。特別是狀態轉移方程,記不清怎麼推導的了,於是在這裡做一下回顧吧 設物品個數為n,每件物品的重量為w i 價值為v i 揹包承重w,我們用乙個二維陣列來表示最大收益,於是得到了方程 if w i 揹包承重j,無法入包 f i j f i 1 j else f i...

簡單dp的狀態轉移方程集合

1.對於任一種n的排列a,定義它的e值為序列中滿足a i i的數的個數。給定n和k k n 1000 問n的排列中e值為k的個數。dp i j 表示i個數的排列中e值為j的個數。假設現在已有乙個e值為j的i的排列,對於新加入的乙個數i 1,將其加入排列的方法有三 1 把它 放最後,加入後e值不變 2...