原题链接传送门
题意:这道题就是让求从三角形顶部到底部结束的路线上传递的最大数字总和。每一步都可以沿着对角线向左或右对角线向下。
输入:第一行输入一个整数N:三角形的行数。
一下N行描述三角形的数据。1 < N <= 100,且三角形中所有整数都砸0–99之间。
输出:从顶部到底部结束的路线上的最大值。
//#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
using namespace std;
int dp[101][101];
int a[101][101];
int main() {
int n;
scanf("%d",&n);
for(int i=1; i<=n; i++) {
for(int j=1; j<=i; j++) {
scanf("%d",&a[i][j]); //用a[i][j]存第i行j列的数值;
}
}
dp[1][1] = a[1][1]; //dp[i][j]存第i行j列的最大值 ;
for(int i=2; i<=n; i++) {
for(int j=1; j<=i; j++) {
if(j == 1) //当第i行第1列时,dp[i][1]只能接受a[i-1][1]的值;
dp[i][j] = dp[i-1][j] + a[i][j];
else if(j == i) //当第i行最后一个时,dp[i][j]只能接受a[i-1][j-1]的值
dp[i][j] = dp[i-1][j-1] + a[i][j];
else //在中间时,dp[i][j]选择接受a[i-1][j]与a[i-1][j-1]中较大的值
dp[i][j] = max(dp[i-1][j-1],dp[i-1][j]) + a[i][j];
}
}
int Max = dp[n][1];
for(int j=1; j<=n; j++) { //判断最后一行中,哪个dp[i][j]最大
if(Max < dp[n][j])
Max = dp[n][j];
}
printf("%d\n",Max);
return 0;
}
记忆化搜索版:
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 105;
int a[N][N],dp[N][N];
int n;
int dfs(int x,int y,int n) {
if(dp[x][y]) //搜过直接返回
return dp[x][y];
if(x == n-1) //搜到最后一行
return a[x][y];
else return dp[x][y] = a[x][y] + max(dfs(x+1,y,n),dfs(x+1,y+1,n));
} //取最优的
int main() {
scanf("%d",&n);
for(int i=0; i<n; i++) {
for(int j=0; j<=i; j++) {
scanf("%d",&a[i][j]);
}
}
int ans = dfs(0,0,n);
printf("%d\n",ans);
return 0;
}