數字三角形問題(動態規劃)
阿新 • • 發佈:2018-12-16
最近在刷動態規劃類的題,刷紫書的259頁題
題目來源:http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Index/problemdetail/pid/1730.html
數字三角形問題
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<Cstring> #include<algorithm> using namespace std; int n; int dp[105][105]; int a[105][105]; int dfs(int i,int j) { if(dp[i][j]>=0) return dp[i][j]; if(i==n) dp[i][j]=a[i][j]; else dp[i][j]=a[i][j]+max(dfs(i+1,j),dfs(i+1,j+1)); return dp[i][j]; } int main() { while(~scanf("%d",&n)) { for(int i=1;i<=n;i++) for(int j=1;j<=i;j++) scanf("%d",&a[i][j]); memset(dp,-1,sizeof(dp)); dfs(1,1); printf("%d\n",dp[1][1]); } }
下面是記憶化搜尋法
#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> using namespace std; int dp[105][105]; int a[105][105]; int n; int dfs(int i,int j) { if(dp[i][j]>=0) return dp[i][j]; if(i==n) dp[i][j]=a[i][j]; else dp[i][j]=a[i][j]+max(dfs(i+1,j),dfs(i+1,j+1)); return dp[i][j]; } int main() { while(~scanf("%d",&n)) { memset(dp,-1,sizeof(dp)); for(int i=1;i<=n;i++) { for(int j=1;j<=i;j++) { scanf("%d",&a[i][j]); } } dfs(1,1); printf("%d\n",dp[1][1]); } }
各自處理邊界的方法不同,遞推是先處理最底層的數然後往上推,遞迴加了一個if語句判斷是否到達邊界