動態規劃的一般步驟
以揹包問題為例
動態規劃本質上為帶備忘錄的窮舉演算法。對動態規劃問題,直接套框架即可:問題有什麼「狀態」,有什麼「選擇」,然後窮舉。
動態規劃演算法適用於組合優化問題,通過劃分子問題的邊界,從子問題開始逐層向上求解,通過子問題之間的依賴關係進行推導計算,最大限度減少重複工作,提高演算法效率。但需要較大的儲存空間來儲存子問題計算的中間結果。
使用動態規劃的問題,必須滿足優化原則
明確「狀態」 -> 定義 dp 陣列/函式的含義 -> 明確「選擇」-> 明確 base case。
首先要寫出所求解的組合優化問題的目標函式和約束條件
確定子問題的結構和邊界,將問題轉化為多步判斷的過程
確定問題是否滿足優化原則
找出子問題之間的依賴關係(優化函式)
找狀態轉移需要歸納思維,說白了就是如何從已知的結果推出未知的部分,如假設已知dp[i-1] 如何推出dp[i]
注意子問題的重疊程度,如果子問題重疊度較低,使用動態規劃演算法在時間複雜度上不會有較大改進
從初值開始自底向上計算子問題的優化函式值
問題描述:有編號分別為a,b,c,d,e的五件物品,它們的重量分別是2,2,6,5,4,它們的價值分別是6,3,5,4,6,每件物品數量只有乙個,現在給你個承重為10的揹包,如何讓揹包裡裝入的物品具有最大的價值總和?
寫出所求解的組合優化問題的目標函式和約束條件
設xi = 0|1
,當xi=0
表示第i
件物品不放入揹包,1則表示放入
設vi
代表第i
件物品的價值,wi
代表第i
件物品的重量
原問題即為求乙個xi
序列,使得總價v
最大且總量w<10
目標函式為:
m ax
(∑xi
∗vi)
max(\sum xi*vi)
max(∑x
i∗vi
)約束條件為:
∑ xi
∗w
i<=10
\sum xi*wi <=10
∑xi∗wi
<=1
0確定子問題的結構和邊界,將問題轉化為多步判斷的過程
把原問題改為:當只能選擇前i
件物品,揹包容量為j
時,揹包的最大價值,用dp[i][j]
表示。
確定問題是否滿足優化原則
揹包問題滿足優化原則,證明過程省略…
找出子問題之間的依賴關係(優化函式)
關係為:dp[i][j] = max(dp[i-1][j],dp[i-1][j-wi]+vi)
說明:dp[i][j]
:當只能選擇前i
件物品,且揹包容量為j
時,揹包的最大價值。
max(dp[i-1][j],dp[i-1][j-wi]+vi)
中dp[i-1][j]
表示不放入第i
件物品,dp[i-1][j-wi]+vi
表示為放入第i
件物品,騰出wi
的重量後獲得的價值
從初值開始自底向上計算子問題的優化函式值
最後計算的子問題的解即為原始問題的解
演算法設計與分析 動態規劃
最大子段和問題 給定由n個整數 包含負整數 組成的序列a1,a2,an,求該序列子段和的最大值。i.當所有整數均為負值時定義其最大子段和為0。所求的最優值為 i.例如,當 a1,a2,a7,a8 1,3,7,8,4,12,10,6 時,最大子段和為 bj是1到j位置的最大子段和 由bj的定義易知,當...
演算法設計與分析 動態規劃
分治技術的問題 子問題是相互獨立的 如果子問題不是相互獨立的,分治演算法將重複計算公共子空間,效率很低 提高效率的方法 從規模最小的子問題開始計算 用恰當資料結構儲存子問題的解,供以後查詢 確保每個子問題只求解一次 優化問題 給定一組約束條件和乙個代價函式,在解空間中搜尋具有最小或最大代價的優化解 ...
演算法練習 跳躍遊戲二(動態規劃)
題目描述 給定乙個非負整數陣列,假定你的初始位置為陣列第乙個下標。陣列中的每個元素代表你在那個位置能夠跳躍的最大長度。你的目標是到達最後乙個下標,並且使用最少的跳躍次數。例如 a 2,3,1,1,4 到達最後乙個下標的最少跳躍次數為 2。先跳躍 1 步,從下標 0 到 1,然後跳躍 3步,到達最後乙...