*51nod 1409
https://blog.csdn.net/stay_accept/article/details/81476358
不懂啊
#include <map> #include <queue> #include <string> #include <math.h> #include <vector> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <string.h> #include <algorithm> using namespace std; inline bool scan_d(int &num) { char in; bool IsN=false; in=getchar(); if(in==EOF) return false; while(in!='-'&&(in<'0'||in>'9')) in=getchar(); if(in=='-') { IsN=true; num=0; } else num=in-'0'; while(in=getchar(),in>='0'&&in<='9') { num*=10,num+=in-'0'; } if(IsN) num=-num; return true; } const int siz=1005; int a[siz][siz]; long long g[siz],dp[2][siz][2]; int main() { long long ans; int n,m,i,j,k,x,y,op; while(scanf("%d%d",&n,&m)!=EOF) { //dp[i][j][k]表示到dii列第j行向上走还是向下走 for(i=1; i<=n; i++) for(j=1; j<=m; j++) scan_d(a[i][j]); for(i=1; i<=n; i++) dp[0][i][0]=dp[0][i][1]=0; for(i=1; i<=m; i++) { x=i&1,y=1-(i&1); for(j=1; j<=n; j++) dp[x][j][0]=dp[x][j][1]=-1; dp[x][0][0]=dp[x][0][1]=0; dp[x][n+1][0]=dp[x][n+1][1]=0; for(j=1; j<=n; j++) { if(a[j][i]==-1) continue; for(k=0; k<=1; k++) { if(dp[y][j][k]!=-1) dp[x][j][0]=max(dp[x][j][0],dp[y][j][k]+a[j][i]); if(dp[y][j][k]!=-1) dp[x][j][1]=max(dp[x][j][1],dp[y][j][k]+a[j][i]); } } //先算出从前一列过来的得分 for(j=2; j<=n; j++) { if(dp[x][j-1][0]!=-1&&a[j][i]!=-1) dp[x][j][0]=max(dp[x][j][0],dp[x][j-1][0]+a[j][i]); } //然后本列进行转移 for(j=1; j<=n; j++) g[j]=-1; g[0]=0; if(dp[x][n][0]!=-1) { //算出经过传送门的得分 op=n; //想下走就找尽可能往下更新的点 while(op>1) { if(dp[x][op][0]==dp[x][op-1][0]+a[op][i]&&dp[x][op-1][0]!=-1) op--; else break; } for(j=1; j<op; j++) { if(a[j][i]==-1) break; g[j]=g[j-1]+a[j][i]; } } //往上走跟往下走是一样的思路 for(j=1; j<n; j++) dp[x][j][0]=max(dp[x][j][0],g[j]); for(j=n-1; j>=1; j--) { if(dp[x][j+1][1]!=-1&&a[j][i]!=-1) dp[x][j][1]=max(dp[x][j][1],dp[x][j+1][1]+a[j][i]); } for(j=0; j<=n; j++) g[j]=-1; g[n+1]=0; if(dp[x][1][1]!=-1) { op=1; while(op<n) { if(dp[x][op][1]==dp[x][op+1][1]+a[op][i]&&dp[x][op+1][1]!=-1) op++; else break; } for(j=n; j>op; j--) { if(a[j][i]==-1) break; g[j]=g[j+1]+a[j][i]; } } for(j=n; j>1; j--) dp[x][j][1]=max(dp[x][j][1],g[j]); } ans=-1; for(i=1; i<=n; i++) ans=max(ans,max(dp[m&1][i][0],dp[m&1][i][1])); printf("%I64d\n",ans); } return 0; }