思路:我们可以直接从4个顶点暴力DP。
DP[1/2/3/4][i][j]表示从某个顶点到(i,j)的最大权值和。
求出之后,我们可以直接枚举相遇点
计算到达最终点的权值和最大即可。
参考代码如下:
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e3 + 10;
const int mod = 1e9 + 7;
int dp[5][maxn][maxn];
int n, m, ans, a[maxn][maxn];
int main()
{
scanf ("%d %d", &n, &m);
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)
dp[1][i][j] = max(dp[1][i - 1][j], dp[1][i][j - 1]) + a[i][j];
for (int i = 1; i <= n; ++i)
for (int j = m; j >= 1; --j)
dp[2][i][j] = max(dp[2][i - 1][j], dp[2][i][j + 1]) + a[i][j];
for (int i = n; i >= 1; --i)
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];
for (int i = n; i >= 1; --i)
for (int j = 1; j <= m; ++j)
dp[4][i][j] = max(dp[4][i + 1][j], dp[4][i][j - 1]) + a[i][j];
for (int i = 2; i < n; ++i)
for (int j = 2; j < m; ++j)
ans = max (ans, dp[1][i - 1][j] + dp[3][i + 1][j] + dp[2][i][j + 1] + dp[4][i][j - 1]),
ans = max (ans, dp[1][i][j - 1] + dp[3][i][j + 1] + dp[2][i - 1][j] + dp[4][i + 1][j]);
printf ("%d\n", ans);
}
京公网安备 11010502036488号