數塔 (論遞迴 搜尋 記憶化搜尋 動態規劃)

2021-09-09 05:53:30 字數 2172 閱讀 2441

題目如下:

在講述dp演算法的時候,乙個經典的例子就是數塔問題,它是這樣描述的: 

有如下所示的數塔,要求從頂層走到底層,若每一步只能走到相鄰的結點,則經過的結點的數字之和最大是多少? 

已經告訴你了,這是個dp的題目,你能ac嗎?

input

輸入資料首先包括乙個整數c,表示測試例項的個數,每個測試例項的第一行是乙個整數n(1 <= n <= 100),表示數塔的高度,接下來用n行數字表示數塔,其中第i行有個i個整數,且所有的整數均在區間[0,99]內。 

output

對於每個測試例項,輸出可能得到的最大和,每個例項的輸出佔一行。 

sample input

157

3 88 1 0

2 7 4 4

4 5 2 6 5

sample output

30
#include#include#include#include#define mm(a,n) memset(a,n,sizeof(a))

#define ll long long

using namespace std;

int a[1001][1001],n;

//求出二維陣列座標(x,y)的最大值。

int fun(int x,int y)

int main()

}cout提交之後:

前面的遞迴演算法,實際上是將整個數字三角形搜尋了一遍,所以,完全可以用深度優先搜尋演算法。就是一條路走到黑,前面沒有路就返回上乙個路口,另選一條路走到黑…..如此反覆,知道所有路全部走遍。

#include#include#include#include#define mm(a,n) memset(a,n,sizeof(a))

#define ll long long

#define maxn 100

using namespace std;

int a[maxn][maxn],n,sum,max;

void dfs(int i,int j)

for(int x=0; x<2; x++)

}int main()

int main()

}cout執行結果:

簡單dp: 

思路: 

**如下:

#include#include#include#includeusing namespace std;

#define mm(a) memset(a,0,sizeof(a))

#define ll long long

ll dp[105][105];

int main()

{ int t;

// freopen("c:\\users\\nuoyanli\\desktop\\acminput.txt","r",stdin);

// freopen("c:\\users\\nuoyanli\\desktop\\acmoutput.txt","w",stdout);

cin>>t;

while(t--)

{int n;

cin>>n;

mm(dp);

for(int i = 0; i < n; i++)

for(int j = 0; j <= i; j++)

cin>>dp[i][j];

for(int i = n - 1; i > 0; i--)

for(int j = n - 1; j > 0; j--)

dp[i - 1][j - 1] += max(dp[i][j],dp[i][j - 1]);

cout執行結果:

數塔 (論遞迴 搜尋 記憶化搜尋 動態規劃)

題目如下 在講述dp演算法的時候,乙個經典的例子就是數塔問題,它是這樣描述的 有如下所示的數塔,要求從頂層走到底層,若每一步只能走到相鄰的結點,則經過的結點的數字之和最大是多少?已經告訴你了,這是個dp的題目,你能ac嗎?input 輸入資料首先包括乙個整數c,表示測試例項的個數,每個測試例項的第一...

記憶化搜尋入門 數塔

time limit 1000ms memory limit 65536kb submit statistic discuss problem description 給定乙個由n行數字組成的數字三角形如下圖所示。試設計乙個演算法,計算出從三角形的頂至底的一條路徑,使該路徑經過的數字總和最大。對於給...

總結 遞迴 記憶化搜尋 遞迴

遞迴函式執行時分為函式 前進段和返回段,真正明白並時刻記住這個才真正掌握了遞迴。寫遞迴時三點 開始定義的 引數,結束條件 邊界 若干if語句 遞迴呼叫及 返回段運算 一般引數中總有乙個代表遞迴層數。遞迴結束返回時要考慮是否修改了全域性變數,並將其改回,這個是為回溯做準備。記憶化搜尋 解決了遞迴時大量...