思路:
将数据以二维数组储存之后如下状态:
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
那么每个点对应的最大数字之和一定是 其正上方的点所对应的和或其正上方左侧点对应的和其中之一加上该点所对应的值。
dp状态转移方程:dp[ i ][ j ] = max(dp[i - 1][ j ], dp[i - 1][j - 1]) + a[ i ][ j ]
#include<iostream>
#include<string>
using namespace std;
int** dp;
int solve(int** a, int n);
int max(int i, int j);
int main() {
int n;
cin >> n;
int** a;
a = new int* [n + 1]; /*初始化两个二维数组,一个存储权值一个存储和值*/
dp = new int*[n + 1];
for (int i = 1; i <= n; i++) {
a[i] = new int[n];
dp[i] = new int[n];
memset(a[i], 0, sizeof(int) * (n + 1));
memset(dp[i], 0, sizeof(int) * (n + 1));
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
cin >> a[i][j]; /*输入权值*/
}
}
cout << solve(a, n);
}
int solve(int** a, int n) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) { /*将每点对应和求出并储存*/
if (i == 1) {
dp[i][j] = a[i][j];
}
else {
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1]) + a[i][j];
}
}
}
int num = -1;
for (int i = 1; i <= n; i++) {
if (dp[n][i] > num) { /*最大值一定在最后一行,在其中找出最大值*/
num = dp[n][i];
}
}
return num;
}
int max(int i, int j) { /*比较函数*/
return (i > j) ? i : j;
}