题意:要求两个人必须相遇一次,A这个人只能从[1,1]到[n,m],B这个人只能从[n,1]到[1,m],A只能向下向右走,B只能向上向右走,问如何选取使得最后值最大。
题解:先分别从四个递推,然后枚举相遇的块,相遇的块肯定不能是边界,因为边界必然有多个块相碰,只能枚举中间的块,但是中间的块对于A只能向下或者向右,如果A是从上面来的,那么必然B是从右边来的,并且A继续向下走,B继续向右走,才能保证只有一个块相碰,如果A是向右走的,那么B必然是从下面来的,A也必须继续向右走,B也必须向上走才能保证只有一个块相遇,最后导出答案即可。
附上代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+5;
int n,m;
int mapp[maxn][maxn];
int dp1[maxn][maxn],dp2[maxn][maxn],dp3[maxn][maxn],dp4[maxn][maxn];
int ans;
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&mapp[i][j]);
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
dp1[i][j]=max(dp1[i-1][j],dp1[i][j-1])+mapp[i][j];
}
}
for(int i=n;i>=1;i--){
for(int j=m;j>=1;j--){
dp2[i][j]=max(dp2[i+1][j],dp2[i][j+1])+mapp[i][j];
}
}
for(int i=n;i>=1;i--){
for(int j=1;j<=m;j++){
dp3[i][j]=max(dp3[i+1][j],dp3[i][j-1])+mapp[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=m;j>=1;j--){
dp4[i][j]=max(dp4[i-1][j],dp4[i][j+1])+mapp[i][j];
}
}
for(int i=2;i<n;i++){
for(int j=2;j<m;j++){
ans=max(ans,dp1[i-1][j]+dp2[i+1][j]+dp3[i][j-1]+dp4[i][j+1]);
ans=max(ans,dp1[i][j-1]+dp2[i][j+1]+dp3[i+1][j]+dp4[i-1][j]);
}
}
printf("%d\n",ans);
return 0;
}