HDU1506 / POJ2339 Largest Rectangle in a Histogram 单调递减栈
生活随笔
收集整理的這篇文章主要介紹了
HDU1506 / POJ2339 Largest Rectangle in a Histogram 单调递减栈
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1.什么是單調棧
- 具有單調性和棧的性質
- 單調遞減棧就是從棧底到棧頂是單調遞減的
- 單調遞增棧就是從棧底到棧頂是單調遞增的
2.單調棧解決的問題
- 以自己為最小值,找到最長的區間;單調遞增棧
- 以自己為最大值,找到最長的區間;單調遞減棧
- 給定一個區間找到這個區間的最大值或最小值
3.單調遞減棧的性質
- 對于第一個出棧的元素,它的右寬一定為0
- 對于第二個出棧的元素,它的右寬為第一個出棧元素的總寬
- 對于第三個出棧的元素,它的右寬為第二個出棧元素的總寬
- 。。。。。。。。
- 直到棧頂元素小于自己,才可以入棧;
- 入棧元素的左寬為上次出棧元素的總寬+1(自身);若無出棧元素,則左寬為1(自身)
- 最后將棧中所有元素出棧,考慮所有情況
(左寬就是左邊比自己小的元素個數,右寬就是右邊比自己小的元素的個數)
4.以下面數據模擬一下單調遞減棧的操作
5.?單調棧的實現
hdu1506(單調遞減棧)poj2339,hrbustoj 2326(需long long)
單調遞減棧:如果是以各個元素為最大值找到最大區間的話 ?q[0]=inf, h=inf-1;
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+10; typedef long long ll; //int a[maxn]; int q[maxn]={-1}; int w[maxn];//記錄左寬,從這個點之前有多少個點的高度大于等于當前點的高度 int main() {int n,h;while(scanf("%d",&n)&&n){int top=0;ll ans=0;for(int i=1;i<=n+1;i++){if(i!=n+1)scanf("%d",&h);elseh=0;//為了讓所有元素出棧if(h>q[top])q[++top]=h,w[top]=1;else{ll cnt=0; //第一個出棧的右寬為0;while(h<=q[top]){ans=max(ans,(w[top]+cnt)*q[top]); //(左寬+右寬)*高度;cnt=cnt+w[top--]; //第(i>1)出棧的右寬為上一個的總寬;}//終于找到比自己小的數字了,可以入棧了,入棧會得到左寬,左寬為上一個出棧元素的總寬+1;q[++top]=h;w[top]=cnt+1;}}printf("%I64d\n",ans);}return 0; } //單調棧:從棧頂到棧底單調遞減?
總結
以上是生活随笔為你收集整理的HDU1506 / POJ2339 Largest Rectangle in a Histogram 单调递减栈的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POJ2823 Sliding Wind
- 下一篇: HDU3410 Passing the