题意:A往下或往右从(1,1)走到(n,m),B往上或往右从(n,1)走到(1,m),输出结果为A与B走过的点的权值和,A与B必需有一交汇点,交汇点权值不计入总和,A与B所走路径除交汇点外不重复
解法:递推DP
dp1[i][j]表示从(1,1)至(i,j)的最大权值和,dp2[i][j]为(n,1)至(i,j),dp3[i][j](1,m)至(i,j),dp4[i][j](n,m)至(i,j),离线计算将其得出
由题目所给条件易知交汇点不可能位于边界,到达交汇点共有两种情况;
#include<iostream> #include<memory.h> #define N 1005 using namespace std; int a[N][N],dp1[N][N],dp2[N][N],dp3[N][N],dp4[N][N]; int main(){ int n,m,ans=0; cin>>n>>m; for(int i=1;i<=n;i++) for(int k=1;k<=m;k++) cin>>a[i][k]; for(int i=1;i<=n;i++) for(int k=1;k<=m;k++) dp1[i][k]=a[i][k]+max(dp1[i][k-1],dp1[i-1][k]); for(int i=n;i>=1;i--) for(int k=1;k<=m;k++) dp2[i][k]=a[i][k]+max(dp2[i][k-1],dp2[i+1][k]); for(int i=1;i<=n;i++) for(int k=m;k>=1;k--) dp3[i][k]=a[i][k]+max(dp3[i][k+1],dp3[i-1][k]); for(int i=n;i>=1;i--) for(int k=m;k>=1;k--) dp4[i][k]=a[i][k]+max(dp4[i+1][k],dp4[i][k+1]); for(int i=2;i<n;i++) for(int k=2;k<m;k++){ ans=max(ans,dp1[i][k-1]+dp2[i+1][k]+dp3[i-1][k]+dp4[i][k+1]); ans=max(ans,dp1[i-1][k]+dp2[i][k-1]+dp3[i][k+1]+dp4[i+1][k]); } cout<<ans<<endl; return 0; }