题意
地图n*m个格点,每个格点有个值。当人走到格点时会获得对应的点数。两个人一个从左下角走到右上角,仅能向上向右走。一个从左上走到右下角,仅能向右向下走。有且仅有一个格点会被两个人走过。
思路
四个方向的dp分别计算从(1,1),(n,1)走到这个点的最大值。和这个点到(1,m),(n,m)的最大值。
显然只有左下角的人从左向右或从下到上时,对应未从上到下或从左到右时相交。
#include<bits/stdc++.h>
using namespace std;
#define first fst
#define second sec
#define sci(num) scanf("%d",&num)
#define scl(num) scanf("%I64d",&num)
#define mem(a,b) memset(a,b,sizeof a)
#define cpy(a,b) memcopy(a,b,sizeof a)
typedef long long LL;
typedef pair<int,int> pair;
const int MAX_N = 1010;
LL dp1[MAX_N][MAX_N];
LL dp2[MAX_N][MAX_N];
LL dp3[MAX_N][MAX_N];
LL dp4[MAX_N][MAX_N];
LL save[MAX_N][MAX_N];
int n,m;
int main() {
mem(dp1,0); mem(dp2,0); mem(dp3,0); mem(dp4,0);
sci(n); sci(m);
for (int i = 1;i <= n;i++)
for (int j = 1;j <= m;j++)
scl(save[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]) + save[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]) + save[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]) + save[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]) + save[i][j];
}
}
LL ans = 0;
for (int i = 2;i < n;i++) {
for (int j = 2;j < m;j++) {
ans = max(ans,dp2[i][j - 1] + dp4[i + 1][j] + dp3[i][j + 1] + dp1[i - 1][j]);
ans = max(ans,dp2[i + 1][j] + dp4[i][j + 1] + dp3[i - 1][j] + dp1[i][j - 1]);
}
}
printf("%I64d\n",ans);
return 0;
}