POJ2559 单调栈

http://poj.org/problem?id=2559

题意都懂,给出数列h1,h2,...hn。代表n个宽为1,高为hi的矩形,求最大连续的矩形面积。

思路:对于每个矩形,当然高已经决定,我们思考它的宽可以为多少。很容易得出它的宽可以向左右延伸到第一个高小于它的矩形之前。也就是说,对于每个hi,找到其左右两边最接近且小于它的数的序号l,r,它的宽就是r-l-1,当然面积就是hi*(ri-li-1),取n个中的最大值当然就是答案了。

使用单调栈算法,我们可以在O(N)的时间复杂度下求出hi左右两边小于它的数的位置。具体看代码。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <stack>
#include <utility>
using namespace std;
typedef long long LL;
stack<int> s;
int n,l[100010],r[100010],h[100010];

int main()
{
    while(scanf("%d",&n)&&n!=0)
    {
        LL ans=0;
        while(!s.empty()) s.pop();  //清栈 
        for(int i=1;i<=n;i++) scanf("%d",&h[i]);h[n+1]=0; //加入一共高为0的矩形,作为最右边界 
        s.push(0); //加入一个高度为0的矩形,作为最左边界 
        for(int i=1;i<=n+1;i++)
        {
            while(h[i]<h[s.top()]) r[s.top()]=i,s.pop();  //如果即将加入矩形高小于栈顶矩形高度,
                                                          //出栈并且栈顶矩形有边界为i,循环此过程 
                                                          //经过此过程,栈顶矩形高度<=待入矩形高度 
            if(h[i]>h[s.top()]) l[i]=s.top();   //如果栈顶矩形<待入矩形,那么待入矩形有边界就是栈顶矩形 
            else l[i]=l[s.top()];   //如果两者相等,待入矩形的左边界与栈顶矩形一致 
            s.push(i);   //最后将待入矩形压栈 
        }
        for(int i=1;i<=n;i++) ans=max(ans,(LL)h[i]*(r[i]-1-l[i]));  //取n个矩形的最大值 
        printf("%lld
",ans);
    }
    
    return 0;
}
原文地址:https://www.cnblogs.com/BakaCirno/p/11296904.html