動態規劃經典例子

2021-10-02 08:03:55 字數 2192 閱讀 9379

求第一層到最後一層的路徑,將該路徑上的所有數字相加後得到的和最大是多少。

#include

using

namespace std;

const

int maxn =

1000

;int f[maxn]

[maxn]

, dp[maxn]

[maxn]

;int

main()

}for

(int i =

1; i <= n; i++

)for

(int i = n -

1; i >=

0; i--)}

cout << dp[1]

[1]<< endl;

//dp[1][1]即為答案

return0;

}

對於數塔問題,貪心法從最上層開始,每次選擇坐下和右下兩個數字中較大的乙個,一直到最底層得到最後結果,顯然這不一定可以得到最優解。然而動態規劃不管是採用自底向上還是自頂向下,都是從邊界開始向上得到目標問題的解。

動態規劃總是會考慮所有子問題,並選擇繼承能得到最優結果的那個,對暫時沒被繼承的子問題,由於重疊子問題的存在,後期可能會再次考慮它們,因此還有機會成為全域性最優的那一部分。

貪心是一種壯士割腕的決策,只要進行了選擇,就不後悔;動態規劃則要看哪個選擇笑到了最後,暫時的領先說明不了什麼。

給定乙個數字序列a1, a2, a3, … , an。求i,j ( 1 <= i <= j <= n ),使得ai + … + aj 最大, 輸出這個最大和。

#include

using

namespace std;

const

int maxn =

10010

;int a[maxn]

, dp[maxn]

;int

main()

dp[0]

= a[0]

; ans =0;

//dp[i]存放以a[i]結尾的連續序列的最大和,需要遍歷i得到最大的才是結果。

for(

int i =

1; i < n; i++)

cout << ans << endl;

return0;

}

在乙個數字序列中,找到乙個最長的子串行(可以不連續),使得這個子串行是不下降(非遞減)的。

#include

using

namespace std;

const

int maxn =

10010

;int a[maxn]

, dp[maxn]

;int

main()

ans =0;

//記錄最大的dp[i]

for(

int i =

1; i <= n; i++)}

ans =

max(dp[i]

, ans);}

cout << ans << endl;

return0;

}

給定兩個字串(或數字序列)a和b,求乙個字串,使得這個字串是a和b的最長公共部分(子串行可以不連線)。

#include

using

namespace std;

const

int maxn =

10010

;string a, b;

int dp[maxn]

[maxn]

;int

main()

for(

int i =

0; i <= b.

length()

; i++

)for

(int i =

1; i <= a.

length()

; i++

)else}}

cout << dp[a.

length()

][b.

length()

];return0;

}

動態規劃經典例子

金明今天很開心,家裡購置的新房就要領鑰匙了,新房裡有一間他自己專用的很寬敞的房間。更讓他高興的是,媽媽昨天對他說 你的房間需要購買哪些物品,怎麼布置,你說了算,只要不超過n元錢就行 今天一早金明就開始做預算,但是他想買的東西太多了,肯定會超過媽媽限定的n元。於是,他把每件物品規定了乙個重要度,分為5...

動態規劃經典例子

總公司擁有高效裝置m臺,準備分給下屬的n個分公司。各分公司若獲得這些裝置,可以為國家提供一定的盈利。問 如何分配這m臺裝置才能使國家得到的盈利最大?求出最大盈利值。其中m 15,n 10。分配原則 每個公司有權獲得任意數目的裝置,但總台數不超過裝置數m。輸入格式 第一行有兩個數,第乙個數是分公司數n...

動態規劃例子

對於由從1到n 1 n 39 這n個連續的整數組成的集合來說,我們有時可以將集合分成兩個部分和相同的子集合。例如,n 3時,可以將集合 分為和。此時稱有一種方式 即與順序無關 n 7時,共有四種方式可以將集合 分為兩個部分和相同的子集合 和 和 和 和 輸入 程式從標準輸入讀入資料,只有一組測試用例...