思路:我们可以直接从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);
}