题目链接:http://codeforces.com/problemset/problem/429/B
题意:给了一个nxm的矩阵,A从(1,1)出发,每次只能走相邻的右边或者下边的格子走到(n,m)停止.B从(n,1)出发,每次只能走相邻的右边或者上边的格子,走到(1,m)停止,两人的路线只能交于一个格子,除相交的格子外,求两人路线上其他格子总和的最大值
分析:动态规划.通过递推求出分别以左上角,左下角,右上角,右下角为出发点到每一个个格子的距离和的最大值.注意右上角和右下角分别和左下角,左上角对应,是一个逆过程.还有一个坑点就是边界没有意义,要赋予极小值.我们枚举每个格子的上下左右对应的两种可能情况(注意不能是到某个格子的距离和再减去该格子的四倍,因为这样有可能两个人的路线相交)
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1010;
int mp[maxn][maxn];
ll dp1[maxn][maxn],dp2[maxn][maxn],dp3[maxn][maxn],dp4[maxn][maxn];
//dp1 left up dp2 left down dp3 right up dp4 right down
const int INF = 0x3f3f3f3f;
int main()
{
int n,m;
cin>>n>>m;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
scanf("%d",&mp[i][j]);
}
}
for(int i = 1; i <= m; i++)
dp1[1][i] = dp1[1][i - 1] + mp[1][i];
for(int i = 2; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
if(j == 1)dp1[i][j] = dp1[i - 1][j] + mp[i][j];
else dp1[i][j] = max(dp1[i - 1][j],dp1[i][j - 1]) + mp[i][j];
}
}
for(int i = 1; i <= m; i++)
dp2[n][i] = dp2[n][i - 1] + mp[n][i];
for(int i = n - 1; i >= 1; i--)
{
for(int j = 1; j <= m; j++)
{
if(j == 1)dp2[i][j] = dp2[i + 1][j] + mp[i][j];
else dp2[i][j] = max(dp2[i + 1][j],dp2[i][j - 1])+ mp[i][j];
}
}
for(int i = m; i >= 1; i--)
dp3[1][i] = dp3[1][i + 1] + mp[1][i];
for(int i = 2; i <= n; i++)
{
for(int j = m; j >= 1; j--)
{
if(j == m)dp3[i][j] = dp3[i - 1][j] + mp[i][j];
else dp3[i][j] = max(dp3[i - 1][j],dp3[i][j + 1]) + mp[i][j];
}
}
for(int i = m; i >= 1; i--)
dp4[n][i] = dp4[n][i + 1] + mp[n][i];
for(int i = n - 1; i >= 1; i--)
{
for(int j = m; j >= 1; j--)
{
if(j == m)dp4[i][j] = dp4[i + 1][j] + mp[i][j];
else dp4[i][j] = max(dp4[i + 1][j],dp4[i][j + 1]) + mp[i][j];
}
}
ll maxx = 0;
// for(int i = 1; i <= n; i++)
// {
// for(int j = 1; j <= m; j++)
// {
// printf("%lld,%lld,%lld,%lld\n",dp1[i][j],dp2[i][j],dp3[i][j],dp4[i][j]);
// }
// }
for(int i = 1; i <= n; i++)
{
dp1[i][0] = dp2[i][0] = dp3[i][0] = dp4[i][0] = -INF;
dp1[i][m + 1] = dp2[i][m + 1] = dp3[i][m + 1] = dp4[i][m + 1] = -INF;
}
for(int i = 1; i <= m; i++)
{
dp1[0][i] = dp2[0][i] = dp3[0][i] = dp4[0][i] = -INF;
dp1[n + 1][i] = dp2[n + 1][i] = dp3[n + 1][i] = dp4[n + 1][i] = -INF;
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
ll ans = dp1[i][j - 1]+dp2[i + 1][j]+dp3[i - 1][j]+dp4[i][j + 1];
maxx = max(maxx,ans);
ans = dp1[i - 1][j] + dp2[i][j - 1] + dp3[i][j + 1] + dp4[i + 1][j];
maxx = max(maxx,ans);
}
}
cout<<maxx<<endl;
return 0;
}