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 }