Codeforces 429B B. Working out
题目意思:
给n*m的矩阵,每个格子有个数,A从(1,1)出发只能向下或右走,终点为(n,m),B从(n,1)出发只能向上或右走,终点为(1,m)。两个人的速度不一样,走到的格子可以获的该格子的数,两人相遇的格子上的数两个人都不能拿。求A和B能拿到的数的总和的最大值。
n,m<=1000
解题思路:
先预处理出每个格子到四个角落格子的路径最大数值,
然后枚举两个人相遇的交点格子,枚举A、B的进来和出去方式,求最大值即可。
注意边界情况。
#include<stdio.h> #include<algorithm> using namespace std; const int MAX = 1010; int ma[MAX][MAX]; int Mrd[MAX][MAX],Mur[MAX][MAX],Mld[MAX][MAX],Mul[MAX][MAX]; int n,m; int i,j; void print(long long a[][MAX]) { for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { printf("%I64d ",a[i][j]); } printf("\n"); } printf("\n"); } void Init() { for(i=1;i<=m;i++) Mrd[1][i]=ma[1][i]+Mrd[1][i-1]; for(j=1;j<=n;j++) Mrd[j][1]=ma[j][1]+Mrd[j-1][1]; for(i=2;i<=n;i++) { for(j=2;j<=m;j++) { Mrd[i][j]=ma[i][j]+max(Mrd[i-1][j],Mrd[i][j-1]); //printf("%d ",Mrd[][]); } } for(i=1;i<=m;i++) Mur[n][i]=ma[n][i]+Mur[n][i-1]; for(j=n;j>=1;j--) Mur[j][1]=ma[j][1]+Mur[j+1][1]; for(i=n-1;i>=1;i--) { for(j=2;j<=m;j++) { Mur[i][j]=ma[i][j]+max(Mur[i+1][j],Mur[i][j-1]); } } for(i=m;i>=1;i--) Mld[1][i]=ma[1][i]+Mld[1][i+1]; for(j=1;j<=n;j++) Mld[j][m]=ma[j][m]+Mld[j-1][m]; for(i=2;i<=n;i++) { for(j=m-1;j>=1;j--) { Mld[i][j]=ma[i][j]+max(Mld[i][j+1],Mld[i-1][j]); } } for(i=m;i>=1;i--) Mul[n][i]=ma[n][i]+Mul[n][i+1]; for(j=n;j>=1;j--) Mul[j][m]=ma[j][m]+Mul[j+1][m]; for(i=n-1;i>=1;i--) { for(j=m-1;j>=1;j--) { Mul[i][j]=ma[i][j]+max(Mul[i+1][j],Mul[i][j+1]); } } } int main() { while(scanf("%d %d",&n,&m)!=EOF) { for(i=1;i<=n;i++) for(j=1;j<=m;j++) scanf("%d",&ma[i][j]); Init(); //print(Mrd); //print(Mur); //print(Mld); //print(Mul); int ans=0,tmp; for(i=2;i<n;i++) { for(j=2;j<m;j++) { tmp=Mrd[i-1][j]+Mur[i][j-1]+Mld[i][j+1]+Mul[i+1][j]; ans=max(tmp,ans); tmp=Mrd[i][j-1]+Mur[i+1][j]+Mld[i-1][j]+Mul[i][j+1]; ans=max(tmp,ans); } } printf("%d\n",ans); } return 0; }