[bzoj1910] [Ctsc2002] Award 颁奖典礼

  应该是第一次写这种图形类的DP。。

  一个“I”可以分成三个矩形。。令f[1..3][i][j][k]表示第几个矩形,下边界为第i行的j~k列,的最大面积。

  然后就是各种优化啊什么的。。。时间复杂度O(nm²)

  一开始一个辅助的区间DP写挂然后调了半天TAT

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 using namespace std;
 5 const int maxn=205;
 6 const int inf=1002333;
 7 int f[2][3][maxn][maxn];
 8 int sm[maxn][maxn],mx1[maxn][maxn],mx2[maxn][maxn];
 9 int n,m,pre,now,ans,tmpmx;
10  
11 int ra;char rx;
12 inline int read(){
13     rx=getchar(),ra=0;
14     while(rx<'0'||rx>'9')rx=getchar();
15     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
16 }
17 inline int max(int a,int b){return a>b?a:b;}
18 inline int min(int a,int b){return a<b?a:b;}
19 int main(){
20     register int i,j,k;
21     n=read(),m=read();
22     for(i=1;i<=n;i++)
23         for(j=1;j<=m;j++)sm[i][j]=sm[i][j-1]+read();
24     for(i=1;i<=m;i++)sm[0][i]=i;
25      
26     now=1,pre=0;
27     for(i=1;i<=2;i++)memset(f[0][i],200,sizeof(f[0][i]));
28     for(i=1;i<=n;i++,swap(now,pre)){
29         for(j=1;j<m;j++)for(k=j+1;k<=m;k++)
30             if(sm[i][k]==sm[i][j-1])
31                 f[now][0][j][k]=(sm[i-1][k]==sm[i-1][j-1]?f[pre][0][j][k]:0)+k-j+1;
32             else f[now][0][j][k]=-inf;
33          
34          
35         for(j=1;j<m;j++)for(k=m,tmpmx=-inf;k>j;k--)
36             tmpmx=max(tmpmx,f[pre][0][j][k]),
37             mx1[j][k]=max(mx1[j-1][k],tmpmx);
38         for(j=2;j<m;j++)for(k=j;k<m;k++)
39             if(sm[i][k]==sm[i][j-1]){
40                 f[now][1][j][k]=f[pre][1][j][k]+k-j+1;
41                 if(sm[i-1][k+1]==sm[i-1][j-2])
42                     f[now][1][j][k]=max(f[now][1][j][k],mx1[j-1][k+1]+k-j+1);
43             }
44             else f[now][1][j][k]=-inf;
45          
46          
47         for(j=2;j<m;j++)mx2[j][j]=f[pre][1][j][j];
48         for(j=1;j<m;j++)
49             for(k=2;k<m-j;k++)
50             mx2[k][k+j]=max(mx2[k][k+j-1],max(mx2[k+1][k+j],f[pre][1][k][k+j]));
51  
52         for(j=1;j<m;j++)for(k=j+2;k<=m;k++){
53             if(sm[i][k]==sm[i][j-1])
54                 f[now][2][j][k]=max(f[pre][2][j][k],mx2[j+1][k-1])+k-j+1;
55             else f[now][2][j][k]=-inf;
56             if(f[now][2][j][k]>ans)ans=f[now][2][j][k];
57         }
58     }
59     printf("%d\n",ans);
60     return 0;
61 }
View Code

 

posted @ 2016-03-21 14:01  czllgzmzl  阅读(232)  评论(0编辑  收藏  举报