参考程序代码:
#include <iostream>
#include <algorithm>
#include <cstring>
#define int long long
using namespace std;
#define N 1010
#define For(i,j,k) for(int i=j;i<=k;i++)
#define IOS ios::sync_with_stdio(),cin.tie(),cout.tie()
int n, m, a[N][N], dp_up[N][N], dp_down[N][N];
void init () {
For (i, 1, n) {
For (j, 1, n) {
dp_up[i][j] = dp_down[i][j] = -1e18;
}
} //将全图初始值赋为一个很小的值
dp_up[1][1] = a[1][1];
dp_down[1][1] = a[1][1]; //将出发点 dp 值赋为 a[1][1]
return ;
}
signed main() {
IOS;
cin >> n >> m;
For (i, 1, n) {
For (j, 1, m) {
cin >> a[i][j];
}
}
init (); //初始化 dp 数组
For (i, 2, n) {
dp_up[i][1] = dp_up[i - 1][1] + a[i][1];
dp_down[i][1] = dp_down[i - 1][1] + a[i][1];
} //初始化第一列,其值为其上面的数的 dp 值加上这个点的权值。
For (j, 2, m) {
For (i, 1, n) {
int t = max (dp_up[i][j - 1], dp_down[i][j - 1]);
dp_up[i][j] = dp_down[i][j] = t + a[i][j];
} //将其先赋值为上一列同一行的数往右走一步得到的价值
For (i, 2, n) {
int t = dp_up[i - 1][j] + a[i][j];
dp_up[i][j] = max (dp_up[i][j], t);
} //模拟向下走得到的价值,将其与向右走得到的价值取 max
for (int i = n - 1; i >= 1; i --) {//因为往上走要先更新下面点的 dp 值,所以需要倒序循环。
int t = dp_down[i + 1][j] + a[i][j];
dp_down[i][j] = max (dp_down[i][j], t);
} //模拟向上走得到的价值,将其与向右走得到的价值取 max
}
//答案为方案1的最大价值与方案2的最大价值中的较大值
cout << max (dp_up[n][m], dp_down[n][m]) << endl;
return 0;
}