數字三角形
題目描述
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
上圖給出了一個數字三角形。從三角形的頂部到底部有很多條不同的路徑。對於每條路徑,把路徑上面的數加起來可以得到一個和,你的任務就是找到最大的和。
注意:路徑上的每一步只能從一個數走到下一層上和它最近的左邊的那個數或者右邊的那個數。
輸入格式
輸入的是一行是一個整數N (1 < N <= 100),給出三角形的行數。下面的N行給出數字三角形。數字三角形上的數的範圍都在0和100之間。
輸出格式
輸出最大的和。
樣例
樣例輸入
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
樣例輸出
30
精髓:
此題是經典的動態規劃題,那爲什麼不用貪心呢?
如果用貪心的話,我們應從第一行第一列的數開始順推,正下方和右下方的數字誰大就加上。
如果用動態規劃的話,我們應從倒數第二行開始逆推,左下數字的最大路徑和和右下數字的最大路徑和誰大就加誰。
以樣例爲例,可以發現動態規劃明顯優於貪心。
貪心:
動態規劃:
參考代碼:
#include<cstdio>
#include<algorithm>
using namespace std;
int main() {
int n,a[105][105],dp[105][105];//dp[i][j]爲狀態,意思是a[i][j]到最
scanf("%d",&n); //後一行的最大路徑和
for(int i=1;i<=n;i++) {
for(int j=1;j<=i;j++) {
scanf("%d",&a[i][j]);
}
}
for(int j=1;j<=n;j++) {
dp[n][j]=a[n][j];//初始化
}
for(int i=n-1;i>=1;i--) {
for(int j=1;j<=i;j++) {
dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+a[i][j];//狀態轉移方
} //程
}
printf("%d",dp[1][1]);
return 0;
}