USACO6.1.2 A Rectangular Barn(rectbarn)

来源:互联网 发布:苹果最新软件源 编辑:程序博客网 时间:2024/06/06 20:06

本题求最大子矩形,所以big barn的方法便不适用了,给出另一种方法:

设h[ i ][ j ]为点(i,j)向上方扩展的最大高度,
l[ i ][ j ]为( i , h[ i ][ j ] )这条线段向左边扩展的最长距离,r[ i ][ j ]为( i , h[ i ][ j ] ) 向右边扩展的最长距离
则 S = h[ i ][ j ] × ( l[ i ][ j ] + r[ i ][ j ] - 1 )。
状态转移:

..............................................................(i,j)是好点
h[ i ][ j ] =  h[ i-1 ][ j ] + 1
l[ i ][ j ]  =  min{ l[ i-1 ][ j ] ,tl[ i ][ j ]  }
r[ i ][ j ]  =  min{ r[ i-1 ][ j ],tr[ i ][ j ]  }
..............................................................(i,j)是坏点
h[ i ][ j ] = 0 
l[ i ][ j ]  = ∞                                 
r[ i ][ j ]  = ∞                                   


/*ID: xsy97051LANG: C++TASK: rectbarn*/#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define MAXN 3005#define INF 0x3f3f3f3fint rr,cc,p,ans=1;bool map[MAXN][MAXN];int h[2][MAXN],r[2][MAXN],l[2][MAXN];int main(){freopen("rectbarn.in","r",stdin);freopen("rectbarn.out","w",stdout);int left[MAXN],right[MAXN];int now=0,last=1;cin>>rr>>cc>>p;if(p==0){cout<<rr*cc<<endl;return 0;}for(int i=1;i<=p;i++){int x,y;cin>>x>>y;map[y][x]=1; } for(int i=1;i<=cc;i++) { now^=1,last^=1;left[0]=0;right[cc+1]=0;for(int j=1;j<=rr;j++)if(map[i][j])left[j]=0;else left[j]=left[j-1]+1; for(int j=rr;j>=1;j--)if(map[i][j])right[j]=0;else right[j]=right[j+1]+1;  for(int j=1;j<=rr;j++) if(map[i][j]) {h[now][j]=0;l[now][j]=r[now][j]=INF;}else{h[now][j]=h[last][j]+1;l[now][j]=min(left[j],l[last][j]);r[now][j]=min(right[j],r[last][j]);ans=max((l[now][j]+r[now][j]-1)*h[now][j],ans);} } cout<<ans<<endl;return 0;}


0 0