http://codeforces.com/problemset/problem/429/B
可以参考这篇文章:
http://blog.csdn.net/pure_lady/article/details/46764839
因为有断点,所以可以预处理四个顶点到任意点的距离最大值,通过拼接得到断点后的距离
然后就是枚举断点的情况,发现断点不可能在边缘,就可以开始写了
#include <iostream> #include <string> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> #include <algorithm> #include <stack> using namespace std; #define MEM(a,b) memset(a,b,sizeof(a)) #define pf printf #define sf scanf #define debug printf("!/m") #define L 1050 #define MAX(a,b) a>b?a:b #define blank pf(" ") int gym[L][L]; int dp1[L][L]; int dp2[L][L]; int dp3[L][L]; int dp4[L][L]; int main() { int n,m,i,j; sf("%d%d",&n,&m); for(i = 1;i<=n;i++) { for(j = 1;j<=m;j++) sf("%d",&gym[i][j]); } MEM(dp1,0); MEM(dp2,0); MEM(dp3,0); MEM(dp4,0); //左上 for(i = 1;i<=n;i++) { //左上 for(j = 1;j<=m;j++) { int tmp = MAX(dp1[i-1][j],dp1[i][j-1]); dp1[i][j] = tmp+gym[i][j]; } //右上 for(j = m;j>=1;j--) { int tmp = MAX(dp3[i-1][j],dp3[i][j+1]); dp3[i][j] = tmp+gym[i][j]; } } for(i = n;i>=1;i--) { //左下 for(j = 1;j<=m;j++) { int tmp = MAX(dp2[i+1][j],dp2[i][j-1]); dp2[i][j] = tmp+gym[i][j]; } //右下 for(j = m;j>=1;j--) { int tmp = MAX(dp4[i+1][j],dp4[i][j+1]); dp4[i][j] = tmp+gym[i][j]; } } int max=0; for(i = 2;i<=n-1;i++) { for(j = 2;j<=m-1;j++) { int tmp = MAX(dp1[i][j-1]+dp2[i+1][j]+dp3[i-1][j]+dp4[i][j+1],dp1[i-1][j]+dp2[i][j-1]+dp3[i][j+1]+dp4[i+1][j]); if(tmp>max) max = tmp; } } pf("%d ",max); return 0; } /* 3 3 1 2 3 4 5 6 7 8 9 */