1. 程式人生 > >POJ 2559 - Largest Rectangle in a Histogram - [單調棧]

POJ 2559 - Largest Rectangle in a Histogram - [單調棧]

style long push += cst tac ++ tar 開始

題目鏈接:http://poj.org/problem?id=2559

題意:

給出 $n(1 \le n \le 10^5)$ 個寬為 $1$,高為 $h_i(0 \le h_i \le 10^9)$ 的矩形,它們從原點開始並排在 $x$ 軸上,

現在要求出,這個合並產生的圖形內部最大的矩形的面積。

Sample Input

7 2 1 4 5 1 3 3

4 1000 1000 1000 1000

0

Sample Output

8

4000

題解:

如果矩形的高度從左到右是單增的,那麽答案必然是嘗試每個矩形的高度作為答案矩形的高度,而寬度則一直延伸到右邊界。

如果出現了某個矩形,其高度比上一個矩形小,那麽可想而知,此前那些矩形往右延伸遇到了當前這個矩形,高度必然要被壓低,

換句說,再往後,答案矩形的高度就受制於當前矩形而非前面那些矩形了。因此,可以將前面所有高過我的矩形統統變成跟我一樣高的。

這樣一來,棧內維護的矩形高度永遠是單增的。

AC代碼:

#include<iostream>
#include<cstdio>
#include<stack>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn=100000+10;

int n,h[maxn];
stack
<pii> S; int main() { while(scanf("%d",&n) && n) { for(int i=1;i<=n;i++) scanf("%d",&h[i]); ll ans=0; for(int i=1;i<=n;i++) { if(S.empty() || h[i]>=S.top().first) { S.push(make_pair(h[i],1)); }
else { int w=0; while(S.size() && h[i]<S.top().first) { w+=S.top().second; ans=max(ans,(ll)w*S.top().first); S.pop(); } S.push(make_pair(h[i],w+1)); } } int w=0; while(!S.empty()) { w+=S.top().second; ans=max(ans,(ll)w*S.top().first); S.pop(); } printf("%I64d\n",ans); } }

POJ 2559 - Largest Rectangle in a Histogram - [單調棧]