题意:在一个n*m的地图中,两个人分别从地图顶上的两个点(1,1),(1,m)出发,向(n,m),(n,1)走去,第一个人只能向右向下走,第二个人只能向左向下走,他们获得的总锻炼值等于他们走到的点的锻炼值之和。但是由于他们两个人如果走到了同一个格子,那么两个人都不加锻炼值。求最大锻炼值是多少。
这道题是一道比较EASY的动态规划题,我们可以从四个角开始递推,然后枚举每一个可能作为他们相交点的地方就可以了(他们不会傻到有多个相交点吧)
代码实现如下:
#include <bits/stdc++.h>
using namespace std;
int MAP[1010][1010];
int ans[5][1010][1010];
int read() {//记得打读入优化可以减少一大段时间
char ch=getchar();
int flag=1,ans=0;
while( ( ch<'0' || ch>'9' ) && ch!='-' ) ch=getchar();
if(ch=='-') flag=-1,ch=getchar();
while(ch>='0' && ch<='9') {
ans=ans*10+ch-'0';
ch=getchar();
}
return ans*flag;
}
int main() {
memset(ans,0,sizeof(ans));
int n,m,i,j,maxn=0;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
MAP[i][j]=read();
for(i=1;i<=n;i++) {//四个角递推
for(j=1;j<=m;j++) {
ans[1][i][j]=max(ans[1][i-1][j],ans[1][i][j-1]);
ans[1][i][j]+=MAP[i][j];
}
}
for(i=n;i>=1;i--) {
for(j=1;j<=m;j++) {
ans[2][i][j]=max(ans[2][i+1][j],ans[2][i][j-1]);
ans[2][i][j]+=MAP[i][j];
}
}
for(i=1;i<=n;i++) {
for(j=m;j>=1;j--) {
ans[3][i][j]=max(ans[3][i-1][j],ans[3][i][j+1]);
ans[3][i][j]+=MAP[i][j];
}
}
for(i=n;i>=1;i--) {
for(j=m;j>=1;j--) {
ans[4][i][j]=max(ans[4][i+1][j],ans[4][i][j+1]);
ans[4][i][j]+=MAP[i][j];
}
}
for(i=2;i<n;i++) {//枚举碰面点
for(j=2;j<m;j++) {
maxn=max(maxn,ans[1][i-1][j]+ans[4][i+1][j]+ans[2][i][j-1]+ans[3][i][j+1]);
maxn=max(maxn,ans[1][i][j-1]+ans[4][i][j+1]+ans[2][i+1][j]+ans[3][i-1][j]);
}
}
printf("%d",maxn);
return 0;
}
by:Chlience