#include using namespace std; typedef long long LL; const int N = 1010; int g[N][N]; // 原始地图 // 1e3 * 1e3 * 1e4 开longlong LL f1[N][N]; // 向右+向下走 LL f2[N][N]; // 向右+向上走 int n, m; /* 现象: 实测 max( max(a,b),max(c,d)) 795 ms max({a,b,c,d}) 1200ms 结论: 放弃max({a,b,c,d}),这个太慢了 */ int main() { // 加快读入 ios::sync_with_stdio(false), cin.tie(0); cin >> n >> m; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) cin >> g[i][j]; memset(f1, -0x3f, sizeof f1); // 有负数,初始化为-INF memset(f2, -0x3f, sizeof f2); // 有负数,初始化为-INF f1[1][1] = f2[1][1] = g[1][1]; // 左上角的数必须拿起来 for (int j = 1; j <= m; j++) { // 第一层循环列数 // 用上一列两种问题的状态更新这一列的状态达到最优 //行数之间也要更新最优的状态 for (int i = 1; i <= n; i++) // 因为是向下走,所以从第一行开始循环 f1[i][j] = max(max(f1[i][j - 1], f2[i][j - 1]) + g[i][j], max(f1[i][j], f1[i - 1][j] + g[i][j])); for (int i = n; i >= 1; i--) // 因为是向上走,所以从第N行开始循环 f2[i][j] = max(max(f1[i][j - 1], f2[i][j - 1]) + g[i][j], max(f2[i][j], f2[i + 1][j] + g[i][j])); } cout << f1[n][m] << endl; // cout << max(f1[n][m], f2[n][m]); // 两种问题取最优(其实不用去max因为{N, M}的格子只能从上面走下来,所以直接去f1[n][m]即可) return 0; }