1. 程式人生 > >紫書動態規劃初步題解——數字三角形問題

紫書動態規劃初步題解——數字三角形問題

題目連結:數字三角形

題目:

數字三角形問題

Time Limit: 1000 ms Memory Limit: 65536 KiB

Problem Description

給定一個由n行數字組成的數字三角形如下圖所示。試設計一個演算法,計算出從三角形的頂至底的一條路徑,使該路徑經過的數字總和最大。
  
對於給定的由n行數字組成的數字三角形,計算從三角形的頂至底的路徑經過的數字和的最大值。

Input

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

Output

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

Sample Input

5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5

Sample Output

30

題解:

紫書已經很詳細地說明了,這裡就給出遞推和遞迴的題解

遞推

#include <cstdio>
#include <algorithm>
using namespace std;

int a[110][110]; 
int d[110][110];
int n;

int main(){
	scanf("%d",&n);
	
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= i; j++){
			scanf("%d",&a[i][j]);
		}
	}
	
	for(int i = 1; i <= n; i++)	d[n][i] = a[n][i];
	
	for(int i = n-1; i >= 1; i--){
		for(int j = 1; j <= i; j++){
			d[i][j] = a[i][j]+max(d[i+1][j],d[i+1][j+1]);
		}
	}
	
	printf("%d\n",d[1][1]);
	
	return 0;
} 

遞迴

#include <cstdio>
#include <algorithm>
using namespace std;

int a[110][110]; 
int d[110][110];
int n;

int dp(int i, int j){
	if(d[i][j]) return d[i][j];
	if(i == n) return a[i][j];	
	return d[i][j] = a[i][j]+max(dp(i+1,j),dp(i+1,j+1));
}

int main(){
	scanf("%d",&n);
	
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= i; j++){
			scanf("%d",&a[i][j]);
		}
	}
	
	printf("%d\n",dp(1,1));
	
	return 0;
}