思路:
动态规划的思想。最优情况下,两个人最多只会重复走一个格子,枚举这个格子。
而且要注意,两条路线在走重复的格子之后,必须各走各的,不要又走成交叉/重复的了。所以对于这个重复的格子来说,它只会有2种情况,如代码。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define mem(a) memset((a), 0, sizeof(a))
const int MAXN = 505;
int a[MAXN][MAXN];
int dp1[MAXN][MAXN], dp2[MAXN][MAXN], dp3[MAXN][MAXN], dp4[MAXN][MAXN];
int main()
{
int n, m;
while (~scanf("%d %d", &n, &m)) {
mem(dp1);
mem(dp2);
mem(dp3);
mem(dp4);
int ans = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++)
scanf("%d", &a[i][j]);
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
dp1[i][j] = max(dp1[i - 1][j], dp1[i][j - 1]) + a[i][j];
}
}
for (int i = n; i >= 1; i--) {
for (int j = 1; j <= m; j++) {
dp2[i][j] = max(dp2[i + 1][j], dp2[i][j - 1]) + a[i][j];
}
}
for (int i = 1; i <= n; i++) {
for (int j = m; j >= 1; j--) {
dp3[i][j] = max(dp3[i - 1][j], dp3[i][j + 1]) + a[i][j];
}
}
for (int i = n; i >= 1; i--) {
for (int j = m; j >= 1; j--) {
dp4[i][j] = max(dp4[i + 1][j], dp4[i][j + 1]) + a[i][j];
}
}
for (int i = 2; i < n; i++) {
for (int j = 2; j < m; j++) {
ans = max(ans, a[i][j] + max(dp1[i - 1][j] + dp2[i][j - 1] + dp3[i][j + 1] + dp4[i + 1][j], dp1[i][j - 1] + dp2[i + 1][j] + dp3[i - 1][j] + dp4[i][j + 1]));
}
}
printf("%d\n", ans);
}
return 0;
}