Largest Rectangle in a Histogram [POJ2559] [单调栈]

题意
一个围挡由n个宽度为1的长方形挡板下端对齐后得到,每个长方形挡板的高度为hi。我们把其抽象成一个图形,问这个图形中包含的面积最大的长方形是多大?

输入
多行数据,每行第一个为n,后面n个数,代表hi
以0为结束

输出
每行一个数

样例输入
7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0
样例输出
8
4000

分析
我们定一个中心为i,矩形高度为Hi,设他能在一个区间[l,r]中存在,必满足j∈[l,r]使Hj≥Hi。如果Hl-1≥Hi,显然可以继续向右扩张,那么Hl-1一定小于Hi,所以l-1是[1,i]中最后一个小于Hi的。那我们从左向右扫维护所有比Hi小的标号,形成一个单调递增的栈,栈顶即是他的左边界。同理维护右边界。

代码

 1 #include<set>
 2 #include<map>
 3 #include<queue>
 4 #include<stack>
 5 #include<cmath>
 6 #include<cstdio>
 7 #include<cstring>
 8 #include<iostream>
 9 #include<algorithm>
10 #define RG register int
11 #define rep(i,a,b)    for(RG i=a;i<=b;++i)
12 #define per(i,a,b)    for(RG i=a;i>=b;--i)
13 #define ll long long
14 #define inf (1<<29)
15 #define maxn 100005
16 using namespace std;
17 int n;
18 ll num[maxn],L[maxn],R[maxn];
19 struct D{
20     int h,id;
21 };
22 stack<D> stk;
23 inline int read()
24 {
25     int x=0,f=1;char c=getchar();
26     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
27     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
28     return x*f;
29 }
30 
31 void work()
32 {
33     int id;
34     while(!stk.empty()) stk.pop();
35     rep(i,1,n)
36     {
37         while(!stk.empty()&&stk.top().h>=num[i])    stk.pop();
38         if(!stk.empty())    id=stk.top().id;
39         else                id=0;
40         L[i]=id+1;
41         stk.push((D){num[i],i});
42     }
43     while(!stk.empty()) stk.pop();
44     per(i,n,1)
45     {
46         while(!stk.empty()&&stk.top().h>=num[i])    stk.pop();
47         if(!stk.empty())    id=stk.top().id;
48         else                id=n+1;
49         R[i]=id-1;
50         stk.push((D){num[i],i});
51     }
52     ll ans=0;
53     rep(i,1,n)    ans=max(ans,num[i]*(R[i]-L[i]+1));
54     printf("%lld\n",ans);
55 }
56 
57 int main()
58 {
59     //freopen("a","r",stdin);
60     while(1)
61     {
62         n=read();if(!n)    return 0;
63         rep(i,1,n) num[i]=read();
64         work();
65     }
66     return 0;
67 }
View Code

 

posted @ 2018-07-20 21:58  iBilllee  阅读(179)  评论(0编辑  收藏  举报