動態規劃經典題目總結

2021-10-23 01:15:57 字數 4314 閱讀 9923

題意

給定乙個由n行數字組成的數字三角形\。試設計乙個演算法,計算出從三角形的頂至底的一條路徑,使該路徑經過的數字總和最大。

對於給定的由n行數字組成的數字三角形,計算從三角形的頂至底的路徑經過的數字和的最大值。

input

輸入資料的第1行是數字三角形的行數n,1≤n≤100。接下來n行是數字三角形各行中的數字。所有數字在0…99之間。

output

輸出資料只有乙個整數,表示計算出的最大值.

樣例輸入57

3 88 1 0

2 7 4 4

4 5 2 6 5

樣例輸出

30思路實現:

剛看到這個題,第一反應是遞迴…,要不是dp的例題我就用遞迴來做了,不過很明顯遞迴肯定是會超時的。就往dp的思路上靠,感覺這個題是入門級題目,思路比較簡單,從最下面一行開始逐一往上進行計算

**:

#include

#include

using

namespace std;

#define max 101;

int dp[

101]

[101];

int n;

int sum[

101]

[101];

intmain()

題意

給出兩個字串,求出這樣的乙個最長的公共子串行的長度:子串行中的每個字元都能在兩個原串中找到,而且每個字元的先後順序和原串中的先後順序一致。

sample input

abcfbc abfcab

programming contest

abcd mnp

sample output4

20思路實現:

這題老師上課也講了,但我感覺理解的不到位,自己再總結一下

①確定狀態:

設f[x][y]表示s[1…x]與t[1…y]的最長公共子串行的長度

②確定狀態轉移方程和邊界條件:

d分三種情況來考慮:

s[x]不在公共子串行中:該情況下fxly]=f[x-1][y]

t[y]不在公共子串行中:該情況下f[x][y]=f[x-1][y-1]

s[x]=ty],s[x]與t[y]在公共子串行中:該情況下,f[x][y]=f[x-1][y-1]+1

f[x][y]取上述三種情況的最大值。

綜上:狀態轉移方程:fx[y]=max

cout << f[ls]

[lt]

<< endl;

return0;

}題意

乙個數的序列ai,當a1 < a2 < … < as的時候,我們稱這個序

列是上公升的。對於給定的乙個序列(a1, a2, …, an),我們可以得到一些上公升的子串行(ai1, ai2, …, aik),這裡1 <= i1 < i2 < … < ik<= n。比如,對於序列(1, 7, 3, 5, 9, 4, 8),有它的一些上公升子串行,如(1, 7), (3, 4, 8)等等。這些子串行中最長的長度是4,比如子串行(1, 3, 5, 8).你的任務,就是對於給定的序列,求出最長上公升子串行的長度。

輸入

輸入的第一行是序列的長度n (1 <= n <= 1000)。第二行給

出序列中的n個整數,這些整數的取值範圍都在0到10000。

輸出

最長上公升子串行的長度。

輸入樣例

71 7 3 5 9 4 8

輸出樣例

4思路實現:

這也是典型的例題,自己總結一下子,加深下理解。

1.找子問題

「求序列的前n個元素的最長上公升子串行的長度」是個子問題,但這樣分解子問題,不具有「無後效性」假設f(n) = x,但可能有多個序列滿足f(n) = x。有的序列的最後乙個元素比 an+1小,則加上an+1就能形成更長上公升子串行;有的序列最後乙個元素不比an+1小……以後的事情受如何達到狀態n的影響,不符合「無後效性」「求以ak(k=1, 2, 3…n)為終點的最長上公升子串行的長度,乙個上公升子串行中最右邊的那個數,稱為該子串行的「終點」。

雖然這個子問題和原問題形式上並不完全一樣,但是只要這n個子問題都解決了,那麼這n個子問題的解中,最大的那個就是整個問題的解。

確定狀態:

子問題只和乙個變數-- 數字的位置相關。因此序列中數的位置k 就是「狀態」,而狀態 k 對應的「值」,就是以ak做為「終點」的最長上公升子串行的長度。狀態一共有n個。

找出狀態轉移方程:

maxlen (k)表示以ak做為「終點」的

最長上公升子串行的長度那麼:

初始狀態:maxlen (1) = 1

maxlen (k) = max + 1

若找不到這樣的i,則maxlen(k) = 1

maxlen(k)的值,就是在ak左邊,「終點」數值小於ak ,且長度最大的那個上公升子串行的長度再加1。因為ak左邊任何「終點」小於ak的子串行,加上ak後就能形成乙個更長的上公升子串行。

**

#include

#include

#include

using

namespace std;

const

int maxn =

1010

;int a[maxn]

;int maxlen[maxn]

;int

main()

for(

int i =

2; i <= n;

++i)

cout <<

*max_element

(maxlen+

1,maxlen + n +1)

;return0;

}

題意

乙個mn的矩陣,找到此矩陣的乙個子矩陣,並且這個子矩陣的元素的和是最大的,輸出這個最大的值。

例如:33的矩陣:

-1 3 -1

2 -1 3

-3 1 2

和最大的子矩陣是:

3 -1

-1 3

1 2input

第1行:m和n,中間用空格隔開(2 <= m,n <= 500)。

第2 - n + 1行:矩陣中的元素,每行m個數,中間用空格隔開。(-10^9 <= m[i] <= 10^9)

output

輸出和的最大值。如果所有數都是負數,就輸出0。

思路

也是經典例子,解法與動態規劃經典題目——最大連續子串行之和題目思想一樣,只不過是二維空間上的拓展。n*n矩陣用二維陣列a[n][n]表示。通過思考可以發現,這道題目與動態規劃經典題目——最大連續子串行之和非常相似,只不過動態規劃經典題目——最大連續子串行之和它是一維的問題,我們可以把每列的元素進行合併為乙個元素(可以定義二維陣列sum,其中sum[i]表示前i行每列數字相加的和,所以sum[j] - sum[i]為一維向量),這樣運用動態規劃經典題目——最大連續子串行之和的思想了。

**:

#include

#include

#include

#include

#include

using

namespace std;

typedef

long

long ll;

const

int n =

1000

;ll arr[n]

[n];

ll dp[n]

[n];

int m, n;

intmain()

} ll ans = arr[1]

[1];

for(

int i =

1; i <= n; i++

)for

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

cout << ans << endl;

}return0;

}

動態規劃 經典題目

made by syx time 2010年7月17日 13 58 47 矩陣連乘 最長公共子串行 最長公共子串行 include char x 8 char y 7 int b 9 8 int c 9 8 void printarray int i1,int j1,int i2,int j2,in...

動態規劃經典題目整理

複雜度 o n w o nw o nw n nn為物品種類,w ww是揹包的重量 目的 使得揹包中的物品價值最大化 單副本揹包問題 每種物品只有一件 k w j ma xk w,j max k w,j max k w j k w,j k w,j 代表揹包重量為w ww,有j jj件物品時候的最大價值...

今日題目 打家劫舍(經典動態規劃題目)

題目描述如下 這是一道關於動態規劃的簡單題,雖說是簡單題,但是關於動態規劃的,看起來就有點恐懼,但看到這道題是簡單題,頓時就覺得 天晴了,雨停了,我覺得我又行了 然後就開始想關於他地動態遞推公式,我一開始地想法是 由於題目要求小偷不能同時偷相鄰兩個房屋,所以我覺得遞迴公式是dp i dp i 2 n...