動態規劃初步

2021-08-29 07:56:14 字數 1369 閱讀 8881

基本原理

類似於遞迴解題,把問題丟給上一層來解決,找出狀態轉換方程即可。當然關鍵問題是如何定義遞迴陣列與找出狀態轉換方程。

hello world

走樓梯:有n階樓梯,每次能走一步或兩步,請問有多少種走法。

設f(n)是n階樓梯不同的走法。則轉移到此狀態的方法有兩種,從n-1階樓梯走一步上來,或者從n-2階樓梯走兩步上來。此時求解f(n)的任務只需扔給f(n-1)和f(n-2)即可,再定好初始值:f(1)=1,f(2)=2;

f(n)=f(1)+f(2)即可求解。

具體實現中應該維護乙個 陣列,減少重複運算。

max sum(hdoj1003)

題目是給出乙個自然數串,求最長子串,使之和最大。

這裡建立狀態陣列時有些許不同,不能設f(n)是前n個數字構成數字串的max sum,這樣雖然最後求解省事(就是f(n)),但是這樣的話狀態轉移方程就不好寫了。這種假設下,f(n)和前面f(i)關係比較複雜,不能簡單地通過num[i]轉換。

而如果將f(n)設為以n為結尾或者開始的子串的最大值,就要好一點。為什麼呢?我們從最簡單地方法來看,暴力搜尋:

for

(int i=

1; i<=n; i++

)for

(int j=i; j<=n; j++

)}

這裡start和stop的值都是變化的,不像走樓梯問題那樣起點是固定的,只有乙個值在變化。這樣設f(n)是以num[n]為結尾的子串的最大值,便固定了結尾,這樣與f(n-1)的關係就是:f(n)=max(num[n], num[n]+f(n-1)) (f[1]=num[1])即如果前面的最大值都是負數,也沒必要還要前面的子串了。

同理,設f(n)是以num[n]為結尾的子串的最大值,則f(n) = max(num[n],num[n]+f(n+1))

**實現:

#include

using namespace std;

intmain()

, f[

100001]=

, s[

100001]=

; cin>>n;

for(

int ii=

1; ii<=n; ii++

)else

}int max =1;

for(

int i=

2; i<=nn; i++)if

(f[i]

> f[max]

) max = i;

cout<<

"case "

<":"

" "<<<

" "

}}

動態規劃初步

動態規劃的實質是通過多階段決策過程解決最優化問題,將每個問題分為若干個相互聯絡的階段,在它的每一階段都需要做出決策,這就是動態規劃與貪心演算法的區別,貪心演算法是以一種貪心規則進行最優運算,但往往得到的結果並不是問題的最優解,而動態規劃則不同,動態規劃是每一步都有乙個決策,保證了最優解是我們要找的整...

動態規劃初步

動態規劃的核心是狀態和狀態轉移方程。計算狀態轉移方程的方法 1 遞迴計算。用直接遞迴的方法計算狀態轉移方程,效率往往十分低下。其原因是相同的子問題被重複計算了多次。2 遞推計算。遞推的關鍵是邊界和計算順序。3 記憶化搜尋。不必事先確定各狀態的計算順序,但需要記錄每個狀態 是否已經計算過 動態規劃基礎...

動態規劃初步探索

下面用乙個很簡單的例子來具體說明一下dp問題的解題過程。題目如下 描述在乙個星期三的早上,某同學想用扔硬幣的方式來決定是否要去上演算法課。他扔 n 次硬幣,如果當中有連續 m 次以上 含 m 次 的結果都是正面,那麼他就去上課,否則就接著睡覺。假設每次扔硬幣扔出的正反兩面的概率都是 0.5。輸入 輸...