寒训5A Largest Rectangle in a Histogram

文章描述了一种算法问题,即如何找到由n个连续长为a[i]、宽为1的矩形拼接成的图形的最大子矩形面积。通过使用单调栈,每次合并单调递增的矩形序列,并计算以当前矩形结尾的最大子矩形面积,从而求得答案。在处理每个矩形时,更新最大面积并保持栈的单调性,最终得到最大子矩形面积。
摘要由CSDN通过智能技术生成

题意

给定n()个连续的长为a[i]而宽为1的矩形,求这些矩形拼接成的图形的最大子矩形的面积。题目有多组样例,当输入的n为0时停止。

思路

假定这些矩形的高度都是单调递增的,那么答案呼之欲出:(高度*它到最后一个矩形的距离)的最大值!但是很遗憾,这些矩形并非单调递增——但也提供了切入点。

考虑下一个矩形比这个矩形矮的情况:如果该矩形和下一个矩形都被选中,那么所组成的矩形高度必定小于等于下一个矩形(换言之:该矩形上面那一块此时已经无用),那么如果我们刷新一遍不选下一个矩形而选入该矩形的情况,就可以安枕无忧地将这两个矩形“合并”。

考虑到前面的矩形已经都被“合并”过,因此前面的矩形组成了一个单调递增的序列,此时我们考虑用上单调栈。每次合并得到的矩形可能比前一个还矮,那就再来一次合并!一直如此,直到没得合并或所得矩形高于栈顶矩形,然后再把这个合并后的庞然大物压入栈顶。每个矩形只会来一次,走一次,时间复杂度满足要求。

那么对于每个矩形,它的最大面积如何计算?考虑合并时的操作,合并时实际上是对一个单调递增的序列求最大子矩形的面积,且要求这个子矩形包括该矩形,那么答案又呼之欲出了:(高度*它到最后一个矩形的距离)!此时的”最后一个矩形“指的是”合并“操作前的栈顶矩形,取出了几个,距离就是多少,然后用一个ans去记录最大值。

代码

#include <iostream>
#include <stack>
using namespace std;
stack<pair<long long, long long> > s;
int n;
long long a[100005];

int main() {

    ios::sync_with_stdio(0);
    cin.tie(0);

    while (true) {
        long long ans = 0;
        cin >> n;
        if (n == 0)
            return 0;
        for (int i = 1; i <= n; ++i) {
            cin >> a[i];
        }
        a[n + 1] = 0;
        for (int i = 1; i <= n + 1; ++i) {
            long long t = 0;
            while (!s.empty() && a[i] < s.top().first) {
                t += s.top().second;
                ans = max(ans, t * s.top().first);
                s.pop();
            }
            s.push(make_pair(a[i], t + 1));
        }
        cout << ans << '\n';
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值