POJ:2556 Largest Rectangle in a Histogram

单调栈的应用。

思路类似于之前做得一个题,L【i】,R【i】,H【i】分别表示长度为H【i】的长方形的左端点和右端点。显然最大面积等于max{H【i】*(R【i】-L【i】+1)}。

H【i】已知,问题在于L【i】,R【i】怎么求。这里用那个题的思路就不行了。就左端点而言,这里需要求从当前位置i往左第一个长度小于H【i】的。这里可以用一个栈来维护。

如果栈顶长度大于等于H【i】则L【i】即i,否则将栈顶元素岀栈直到栈顶为空或者小于H【i】。栈空说明栈里所有元素都比H【i】大或者相等,则L【i】=1,如果栈顶元素小于H【i】,那么H【i】即栈顶当前元素对应位置。然后将当前位置元素入栈。

 为什么这样是正确的呢。因为栈始终是单调非减的。栈顶始终是最大的。但凡在该位置时岀栈的,一定是大于等于当前位置长度的。如果下一个位置的长度比当前位置长度要小,它自然也比之前岀栈这些要小。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <algorithm>
#define ll long long
#define INF 2139062143
#define inf -2139062144
#define MOD 20071027
#define MAXN 100005
using namespace std;
ll h[MAXN],L[MAXN],R[MAXN];
int main()
{
    int n;
    while(scanf("%d",&n)&&n)
    {

        for(int i=1; i<=n; ++i)
            scanf("%lld",&h[i]);
        L[1]=1;
        R[n]=n;
        stack<int> left;
        left.push(1);
        int t;
        for(int i=2; i<=n; ++i)
        {
            while(!left.empty()&&h[left.top()]>=h[i]) left.pop();
            if(left.empty()) L[i]=1;
            else L[i]=left.top()+1;
            left.push(i);
        }
        stack<int> right;
        right.push(n);
        for(int i=n-1; i>=1; --i)
        {
            while(!right.empty()&&h[right.top()]>=h[i]) right.pop();
            if(right.empty()) R[i]=n;
            else  R[i]=right.top()-1;
            right.push(i);
        }
        ll ans=0;
        for(int i=1; i<=n; ++i)
            ans=max(ans,h[i]*(R[i]-L[i]+1));
        printf("%lld\n",ans);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值