[POJ2559] Largest Rectangle in a Histogram(单调栈)

传送门:Largest Rectangle in a Histogram

题意

给定一系列高为 hi,宽为 1 的矩形,找出这些矩形组成的图形中最大的矩形面积。

思路

要求最大的矩形面积,我们只要知道以每个矩形的高度向右最远能够延申到的宽度,将这个宽度乘以高度就是它的面积,找出其中最大的一个就是我们要求的值。要得到这个宽度,我们可以采用一个单调递减栈(每次压栈的值都比栈顶的值大),并利用一个 startPos 维护以某个高度 h 最远能向左延申到的下标(最左最右本质上是相同的,目的都是求出宽度)。每次弹栈时,由于我们知道栈顶的高度必定比当前要压栈的高度要大,所以当前高度就能够延申到栈顶的高度最左能够延申到的下标。于是,为了维护栈的单调性,最后一个出栈的高度最左能够延申到的下标,就是当前要压栈的高度最左能够延申到的下标。每次弹栈求出栈顶的高度最左能延申到的面积,更新最大值。

当所有高度都遍历过一遍后,栈中可能还会有剩余的矩形未处理。这时,我们就把它们全部弹出,当前下标就是 n,弹出时计算面积,更新最大值即可。

代码

#include <iostream>
#include <cstdio>
#include <stack>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1e5+5;
struct Node
{
    ll height;
    int startPos; //该高度能向左延申到的坐标
    Node() {}
    Node(ll height, int startPos): height(height), startPos(startPos) {}
};
int n;
stack<Node> monoStack;
ll h, ans;

void solve()
{
    ans = 0;
    monoStack.push(Node(-1, 0));
    for(int i = 0; i < n; ++i)
    {
        scanf("%I64d", &h);
        ll height;
        int startPos = INF;
        while(!monoStack.empty() && h <= monoStack.top().height)
        {
            height = monoStack.top().height;
            startPos = monoStack.top().startPos;
            monoStack.pop();
            ans = max(ans, (ll)(i - startPos)*height);
        }
        monoStack.push(Node(h, min(i, startPos))); //最后一个出栈的startpos就是h最左能延申到的位置,如果没有出栈的,那就是i本身
    }
    while(!monoStack.empty()) //最后将所有结点弹出
    {
        ans = max(ans, (ll)(n - monoStack.top().startPos)*monoStack.top().height);
        monoStack.pop();
    }
    printf("%I64d\n", ans);
}

int main()
{
    while(scanf("%d", &n) && n)
    {
        solve();
    }
    return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值