您的位置:首页 > Web前端 > AngularJS

USACO6.1.2 A Rectangular Barn(rectbarn)

2015-02-05 19:57 441 查看
本题求最大子矩形,所以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: xsy97051
LANG: C++
TASK: rectbarn
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

#define MAXN 3005
#define INF 0x3f3f3f3f

int 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: