Largest Rectangle in a Histogram POJ
阿新 • • 發佈:2018-12-11
題解:可以先看下CCF這個題:傳送門
這種做法豈不是列舉麼,如果確定了長方形的左端點L和右端點R,那麼最大可能的高度就是min{hi|L<=i<R}。這樣我們就得到了一個O(n^3)的演算法。如果對計算區間最小值進行一些優化,那麼複雜度可以將為O(N^2).但是即使這樣,仍然無法在規定時間內求得答案。設面積最大的長方形的左端時L,右端是R,高度是H。如果h(L-1)>=H,那麼左端點就可以更新為L-1,從而可以得到更大的長方形。這與假設矛盾,因此h(L-1)<H。同理可得h(R)<H,並且高度H=min{hi|L<=i<R}。因此,固定可以這樣的H的i並進行分析。此時,L是滿足h(j-1)<h(i)的最大的(j<=i)。R是滿足h(j)<h(i)的最小的(j>i)。我們把兩個值分別表示為L[I]和R[i]。如果能求出L[i]和R[i],那麼最大的面積就是max{h(i)*(R[i]-L[i])。
用一個棧提前把L[i]和R[i]提前打好就好了
附上程式碼:
#include<iostream> #include<cstdio> using namespace std; typedef long long ll; const int maxn=1e5+50; int n; int h[maxn]; int l[maxn],r[maxn]; int st[maxn]; void solve() { int t=0; for(int i=0;i<n;i++){ while(t>0&&h[st[t-1]]>=h[i]){ t--; } l[i]=t==0?0:(st[t-1]+1); st[t++]=i; } t=0; for(int i=n-1;i>=0;i--){ while(t>0&&h[st[t-1]]>=h[i]){ t--; } r[i]=t==0?n:st[t-1]; st[t++]=i; } ll res=0; for(int i=0;i<n;i++){ res=max(res,(long long)h[i]*(r[i]-l[i])); } printf("%lld\n",res); } int main() { while(scanf("%d",&n)!=EOF&&n){ for(int i=0;i<n;i++){ scanf("%d",&h[i]); } solve(); } return 0; }