動態規劃筆記

2021-06-26 02:08:00 字數 1433 閱讀 1700

動態規劃,維基上面的解釋是:

動態規劃(英語:dynamic programming,dp)[1]是一種在數學、電腦科學和經濟學中使用的,通過把原問題分解為相對簡單的子問題的方式求解複雜問題的方法。 動態規劃常常適用於有重疊子問題[2]和最優子結構性質的問題,動態規劃方法所耗時間往往遠少於樸素解法。

動態規劃背後的基本思想非常簡單。大致上,若要解乙個給定問題,我們需要解其不同部分(即子問題),再合併子問題的解以得出原問題的解。 通常許多子問題非常相似,為此動態規劃法試圖僅僅解決每個子問題一次,從而減少計算量: 一旦某個給定子問題的解已經算出,則將其記憶化儲存,以便下次需要同乙個子問題解之時直接查表。 這種做法在重複子問題的數目關於輸入的規模呈指數增長時特別有用。

核心是重複子問題和記憶化儲存,要點是空間換時間。最近幾天寫了幾個動態規劃的題目,對於動態規劃這個演算法有了一些體會和認識。

把動態規劃型別的題目抽象一下:乙個有限元集合,存在乙個定義域為這個集合的函式f(a),現要選定集合內若干個元素,使得f(b1)+f(b2)+f(b3)+...f(bm)達到極值。

明顯看出,所有情況有2^n種,若要考慮排列則是n!種,也就是說窮舉演算法的時間複雜度超過了多項式時間,空間複雜度為o(n)。但是如果在窮舉的過程中,有很多種相同情況,那麼我們就可以把這些情況的最佳解記錄下來,減少搜尋次數和時間。

0-1揹包問題,乙個物體有兩種情況:裝和不裝。這就產生了兩個子問題,如果裝,產生了的子問題是空間減少了物體的體積,規模減小1;如果不裝,產生的子問題是揹包體積不變,規模減小1。如此看來,我們可以使用乙個物體數乘揹包空間大小的乙個矩陣,儲存所有情況,來解決這一問題。這時,時間複雜度降為o(n^2),空間複雜度o(n^2),這是乙個以空間換時間的演算法。

以0-1揹包問題為例,部分**:

/* 一次加入乙個物體進行搜尋 */

for ( i = 1; i <= num; i++ )

/* 否則不放入,繼承上一物體的價值 */

else

}}

但是當資料量比較大的時候,記憶體很可能不夠,當處理最長公共子串行的時候,資料量達到了2k,此時陣列的大小達到了16mb,消耗量比較大。若提前考慮有效資料的數量,及時清除不需要的資料,就能夠減小儲存空間。比如最長公共子串行問題,長度n的情況只與n和n-1的情況相關,因此陣列可以減少到2n大小,將複雜度降到o(n)。

/* 一次加入乙個物體進行搜尋 */

for ( i = 1; i <= num; i++ )

/* 否則不放入,繼承上一物體的價值 */

else

}}

想了想,動態規劃的數學表示式是遞迴,當前狀態的情況與以前幾個狀態相關,為了減少遞迴深度,需要儲存前幾個狀態,於是寫成了迴圈形式,用陣列儲存所有結果。若能夠提前判斷出和之前幾個狀態數相關,就可以減小空間開銷了。

ACM 動態規劃筆記

2.解決動態規劃問題,要先找出動態轉移方程來,動態轉移方程怎麼找呢?首先得定好,用哪幾個因子,可以明確的表示好乙個狀態,然後,再通過樣例或者特例或者硬想,找出子問題和父問題的關係,或者說,子問題怎麼push,可以影響到父問題?我感覺可以放開思路想,放心大膽的想,假設你不會動態規劃,讓你暴力搜尋,你會...

學習筆記 動態規劃

動態規劃 多階段決策 意義 求解決策過程最優化的數學方法 基本思想 將待求解的問題分為若干個階段,即若干個互相聯絡的子問題,在求解子問題的過程中逐步推導出原問題的解。核心 在求解子問題的過程中,儲存子問題的解。注1 動態規劃的思想實際上和遞迴相似。都是通過逐步推導,得到答案。而用它們解題時的核心也都...

動態規劃筆記 二

題目 小兵向前衝 題目描述 n m的棋盤上,小兵要從左下角走到右上角,只能向上或則向右走,問由多少種走法。include using namespace std intforward int n,int m if n 1 m 1 條狀棋盤 return forward n,m 1 forward n...