

题意还是十分好理解的,其实也就分成三种状态来转移而已。
1 #include<cstring> 2 #include<cmath> 3 #include<iostream> 4 #include<algorithm> 5 #include<cstdio> 6 #define N 207 7 #define inf 1000000009 8 using namespace std; 9 10 int n,m,ans; 11 12 int f[4][N][N][N],s[N][N],x1[N][N][N],x2[N][N][N]; 13 14 int main() 15 { 16 scanf("%d%d",&n,&m); 17 memset(x1,192,sizeof(x1)); 18 memset(x2,192,sizeof(x2)); 19 memset(f,192,sizeof(f));//先赋值为一个最大值。 20 for (int i=1;i<=m;i++) 21 for (int j=1;j<=m;j++) 22 f[1][0][i][j]=0;//第零行初始化为0,表示没有长度。 23 int x; 24 for (int i=1;i<=n;i++) 25 for (int j=1;j<=m;j++) 26 { 27 scanf("%d",&x); 28 s[i][j]=s[i][j-1]+x;//处理前缀和。 29 } 30 for (int i=1;i<=n;i++) 31 { 32 for (int j=1;j<=m;j++) 33 for (int k=j;k<=m;k++) 34 if (s[i][k]-s[i][j-1]==0)//如果这一段都是空地的话。 35 { 36 f[1][i][j][k]=max(f[1][i-1][j][k],0)+k-j+1;//如果上一层是有的话,就继续转移。 37 f[2][i][j][k]=max(x2[i-1][j][k],f[2][i-1][j][k])+k-j+1;//也是一样的道理,从上一层的最大值来转移。 38 f[3][i][j][k]=max(x1[i-1][j][k],f[3][i-1][j][k])+k-j+1; 39 ans=max(ans,f[3][i][j][k]);//ans每次从当前I型中取最大值。 40 } 41 for (int l=0;l<=m-1;l++) 42 for (int j=1;j+l<=m;j++) 43 { 44 int k=j+l; 45 x1[i][j][k]=max(max(x1[i][j+1][k],x1[i][j][k-1]),f[2][i][j+1][k-1]);//x1数组是用来更新第三块矩阵的,代表了第二号矩阵。 46 } 47 for (int l=m-1;l>=0;l--) 48 for (int j=1;j+l<=m;j++) 49 { 50 int k=j+l; 51 x2[i][j][k]=max(max(x2[i][j-1][k],x2[i][j][k+1]),f[1][i][j-1][k+1]);//x2数组是用来更新第二块矩阵的,代表了第一号矩阵。 52 } 53 //x1,x2表示衔接矩阵。 54 } 55 printf("%d\n",ans); 56 }
bzoj1910: [Ctsc2002] Award 颁奖典礼
原文:http://www.cnblogs.com/fengzhiyuan/p/7632849.html