ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

NC50965 Largest Rectangle in a Histogram

2022-07-02 21:36:14  阅读:141  来源: 互联网

标签:直方 int s2 s1 NC50965 histogram Histogram rectangles Rectangle


NC50965 Largest Rectangle in a Histogram

题目

题目描述

A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rectangles have equal widths but may have different heights. For example, the figure on the left shows the histogram that consists of rectangles with the heights 2, 1, 4, 5, 1, 3, 3, measured in units where 1 is the width of the rectangles:
img
Usually, histograms are used to represent discrete distributions, e.g., the frequencies of characters in texts. Note that the order of the rectangles, i.e., their heights, is important. Calculate the area of the largest rectangle in a histogram that is aligned at the common base line, too. The figure on the right shows the largest aligned rectangle for the depicted histogram.

输入描述

The input contains several test cases. Each test case describes a histogram and starts with an integer n, denoting the number of rectangles it is composed of. You may assume that \(1 \leq n \leq 100000\) . Then follow n integers \(h1\dots hn\), where \(0 \leq h_i \leq 1000000000\). These numbers denote the heights of the rectangles of the histogram in left-to-right order. The width of each rectangle is 1. A zero follows the input for the last test case.

输出描述

For each test case output on a single line the area of the largest rectangle in the specified histogram. Remember that this rectangle must be aligned at the common base line.

示例1

输入

7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0

输出

8
4000

说明

Huge input, scanf is recommended.

题解

思路

知识点:单调栈。

如果枚举区间,获取区间最小直方,显然是很复杂的。因为区间不同导致的最小值不同,虽然可以用单调队列动态获取某一区间的最小值,但问题在于端点的可能有 \(n^2\) 个,所以复杂度是 \(O(n^2)\) 是不可接受的。

但是换一种角度,我们枚举直方,一共就 \(n\) 个,枚举 \(n\) 次即可。那么固定一个直方,最大的可伸展长度取决于左右第一个小于它的位置,找到长度乘以直方高度就是矩形面积了。

对于一个直方,左边最邻近小于用单调递增栈从左到右维护,右边同理从右到左维护,注意找到的位置是小于的那个直方的位置,而不是可伸展最大的位置,因此左边的需要加一,右边的需要减一。

时间复杂度 \(O(n)\)

空间复杂度 \(O(n)\)

代码

#include <bits/stdc++.h>

using namespace std;

int h[100007];
int l[100007], r[100007];
///最大矩形高度肯定是某个矩形高度
///对于一个矩形,水平扩展距离取决于第一个比他小的,两边都是
///于是对每个矩形,用单调递增栈获得他左侧/右侧第一个比它小的矩形位置,就能知道左侧/右侧扩展距离
int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int n;
    while (cin >> n, n) {
        for (int i = 0;i < n;i++) cin >> h[i];
        stack<int> s1;
        for (int i = 0;i < n;i++) {
            while (!s1.empty() && h[s1.top()] >= h[i]) s1.pop();
            l[i] = s1.empty() ? 0 : s1.top() + 1;///左侧大于等于的第一个位置
            s1.push(i);
        }
        stack<int> s2;
        for (int i = n - 1;i >= 0;i--) {
            while (!s2.empty() && h[s2.top()] >= h[i]) s2.pop();///一定是大于等于,于是栈就是严格递减栈,元素是最靠右的
            r[i] = s2.empty() ? n - 1 : s2.top() - 1;///右侧大于等于的最后一个位置
            s2.push(i);
        }
        long long ans = 0;
        for (int i = 0;i < n;i++)
            ans = max(ans, (r[i] - l[i] + 1LL) * h[i]);
        cout << ans << '\n';
    }
    return 0;
}

标签:直方,int,s2,s1,NC50965,histogram,Histogram,rectangles,Rectangle
来源: https://www.cnblogs.com/BlankYang/p/16438580.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有