依然是按照动态规划dp的顺序来
step1:定义状态表示 f[i][j]表示的是到,j这个坐标的结点时的最大权值
step2: 定义状态方程
i,j坐标可能是从i-1 j-1 到i,j 也可能是从i-1 j到 i,j 所以状态方程应该是
f[i][j] = max(f[i-1][j-1],f[i-1][j]) + a[i][j]
step3:初始化
初始化依然要要求1.不越界 2.不影响正确性
越界的问题我们只要从1开始计数,自然而然就有一层下标为0的包裹起来防止越界了
我们只要考虑一下正确性就行了
1,1这个坐标的最大权值应该就是它本身,我们只要把原来的数组全设置为0,那么算出来的值就是a[1][1]本身
2,1这个坐标的最大权值应该是 1,1这个点的最大权值和 0,1这个点权值 取大的 再加它本身 我们应该选择1,1 所以 0,1不能比1,1的权值大 刚好我们0,1权值也设置的是0,所以没问题
正确性得到了保证了
step4:结果
遍历最后一个结果的f数组的值 找最大的 就是最大权值的和了
下面我们开始实现代码
#include <iostream>
using namespace std;
const int N = 1010;
int a[N][N];
int f[N][N];int n;
int main()
{cin >> n;for (int i = 1; i <= n; i++){for (int j = 1; j <= i; j++){cin >> a[i][j];}}for (int i = 1; i <= n; i++){for (int j = 1; j <= i; j++){f[i][j] = max(f[i - 1][j], f[i - 1][j - 1]) + a[i][j];}}int ret = -1e9;for (int j = 1; j <= n; j++){ret = max(ret, f[n][j]);}cout << ret << endl;
}