分析
一个节点到左上,右上,左下,右下的最大值路径是确定的。那么我们考虑见面的点是哪个点。因为见面点是不能计算贡献的,所以我们考虑第一个人和第二个人是分别从哪个方向来的。经过讨论也只有两种可能。
枚举每一个点算出值就可以了。时间复杂度为 。
代码
#include<bits/stdc++.h>
using namespace std;
int read() {
int x = 0,f = 0;char ch = getchar();
while(!isdigit(ch)) {if(ch == '-') f = 1;ch = getchar();}
while(isdigit(ch)) {x = x * 10 + ch - '0';ch = getchar();}
return f ? -x : x;
}
const int N = 1010;
int a[N][N],dp[4][N][N],n,m;
int main()
{
n = read();m = read();
for(int i = 1;i <= n;i++) {
for(int j = 1;j <= m;j++) {
a[i][j] = read();
}
}
for(int i = 1;i <= n;i++) {
for(int j = 1;j <= m;j++)
dp[0][i][j] = max(dp[0][i][j-1],dp[0][i-1][j]) + a[i][j]; // 左上
for(int j = m;j >= 1;j--)
dp[1][i][j] = max(dp[1][i][j+1],dp[1][i-1][j]) + a[i][j]; // 右上
}
for(int i = n;i >= 1;i--) {
for(int j = 1;j <= m;j++)
dp[2][i][j] = max(dp[2][i+1][j],dp[2][i][j-1]) + a[i][j]; // 左下
for(int j = m;j >= 1;j--)
dp[3][i][j] = max(dp[3][i+1][j],dp[3][i][j+1]) + a[i][j]; // 右下
}
int ans = 0;
for(int i = 2;i < n;i++) {
for(int j = 2;j < m;j++) {
ans = max(ans,dp[0][i][j-1]+dp[3][i][j+1]+dp[1][i-1][j]+dp[2][i+1][j]);
ans = max(ans,dp[0][i-1][j]+dp[3][i+1][j]+dp[1][i][j+1]+dp[2][i][j-1]);
}
}
cout << ans << endl;
return 0;
}
京公网安备 11010502036488号