题目链接:http://acm.uestc.edu.cn/#/problem/show/1651
题意:
为了迎接本科的评教工作,Uestc迎来了很多专家。
为了Uestc的荣誉,我们当然是想尽可能多的增加专家的好感度。
然而,Uestc并不是完美无暇的,所以现在我们需要给专家们规划出一条最能增加好感度的路线。 但是最近大家都比较忙,所以你的辅导员将这个艰巨的工作交给了你的室友。Uestc可以被看成是n×m
的矩阵A。专家团队有两个,一个从(1,1)点出发,需要到达(n,m)点。只能从(i,j)走到(i+1,j)或(i,j+1)。 另一个从(n,1)出发, 需要到达(1,m)点。只能从(i,j)走到(i,j+1)或(i−1,j)。
专家们会在点(i,j)获得Aij的好感度。但是当两路专家相遇时,他们会交换一下各自的意见,然后会发现这个学校女生太少了。所以他们不会获得在这个点应得的好感度。幸运的是,在整个行程中, 两路专家的路径只有一个格子是重合的。你的室友并不能胜任这个困难的工作,所以他带着他的问题找到了聪明的你。

解法:直接预处理出从四个角到每个点的最大好感度,然后枚举在哪个点相遇,更新答案即可。
注意有2种情况

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1010;
int n, m, ans, a[maxn][maxn], dp[4][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[0][i][j]=max(dp[0][i][j],dp[0][i-1][j]+a[i][j]);
            dp[0][i][j]=max(dp[0][i][j],dp[0][i][j-1]+a[i][j]);
        }
    }
    for(int i=n; i>=1; i--){
        for(int j=1; j<=m; j++){
            dp[1][i][j]=max(dp[1][i][j],dp[1][i+1][j]+a[i][j]);
            dp[1][i][j]=max(dp[1][i][j],dp[1][i][j-1]+a[i][j]);
        }
    }
    for(int i=n; i>=1; i--){
        for(int j=m; j>=1; j--){
            dp[2][i][j]=max(dp[2][i][j], dp[2][i+1][j]+a[i][j]);
            dp[2][i][j]=max(dp[2][i][j], dp[2][i][j+1]+a[i][j]);
        }
    }
    for(int i=1; i<=n; i++){
        for(int j=m; j>=1; j--){
            dp[3][i][j]=max(dp[3][i][j],dp[3][i-1][j]+a[i][j]);
            dp[3][i][j]=max(dp[3][i][j],dp[3][i][j+1]+a[i][j]);
        }
    }
    for(int i=2; i<n; i++){
        for(int j=2; j<m; j++){
            ans = max(ans, dp[0][i-1][j]+dp[2][i+1][j]+dp[1][i][j-1]+dp[3][i][j+1]);
            ans = max(ans, dp[0][i][j-1]+dp[2][i][j+1]+dp[1][i+1][j]+dp[3][i-1][j]);
        }
    }
    printf("%d\n", ans);
    return 0;
}