Largest Rectangle in a Histogram POJ - 2559 (单调栈详尽版)

部署运行你感兴趣的模型镜像

题意:在一个条形统计图中求最大的矩形面积,宽为1,高由题目给出。

思路:维护一个单调递增序列,若当前进栈值小于栈顶元素,说明栈顶的矩形已经不能再往右边延伸了,那么算出它的面积与ans进行比较。如此将整个数组扫一遍即可求得答案。具体看代码注释

#include<stdio.h>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=1e5+5;
int n,minn[N];
LL ans;
struct node
{
    LL x;//高度,LL型防止乘法溢出
    int y;//可以延伸到最左边的下标值
}a[N];
int main()
{
    int head,tail;
    while(~scanf("%d",&n)&&n)
    {
        ans=head=0,tail=-1;
        a[0].x=a[n+1].x=0;//手动插入第一个和最后一个值(貌似第一个不用手动进栈也行,不过最后一个是一定要的),并且最后一个的x必须是0,为的是最后将栈中的所有元素弹出,因为维护的是一个单调递增序列
        a[0].y=0,a[n+1].y=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a[i].x);//高度
            a[i].y=i;//默认可延伸到的最左边是自己
        }
        for(int i=1;i<=n+1;i++)//注意是0——n+1
        {
            while(head<=tail&&a[i].x<a[minn[tail]].x)//当前进栈的高度小于栈顶矩形的高度
            {
                ans=max(ans,(i-a[minn[tail]].y)*a[minn[tail]].x);//计算出栈顶矩形的面积
                a[i].y=a[minn[tail]].y;//将当前矩形可向左可延伸的下标换成栈顶矩形可向左可延伸的下标
                tail--;//出栈
            }
            minn[++tail]=i;//当前矩形进栈
        }
        printf("%lld\n",ans);
    }
}

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:


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.

Input

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<=n<=100000. Then follow n integers h1,...,hn, where 0<=hi<=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.

Output

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.

Sample Input

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

Sample Output

8
4000

Hint

Huge input, scanf is recommended.

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

### 关于直方图中最大矩形面积的算法 要解决直方图中的最大矩形面积问题,可以采用一种基于单调栈的方法来实现高效的解决方案。这种方法的时间复杂度为 \(O(n)\),其中 \(n\) 是输入数组的高度数量。 以下是解决问题的核心思路: 1. 使用一个栈存储柱状图的索引。 2. 遍历整个高度数组,在遍历时维护一个递增顺序的栈。 3. 当遇到当前高度小于等于栈顶对应的高度时,弹出栈顶并计算以该高度为基础的最大矩形面积[^1]。 4. 如果栈为空,则宽度为当前索引;如果栈不为空,则宽度为当前索引减去新的栈顶索引再减一[^2]。 5. 继续处理直到完成所有元素的扫描,并清空栈以确保所有可能的矩形都被考虑[^3]。 #### Python 实现代码 下面是一个完整的 Python 实现方案: ```python def largest_rectangle_area(heights): stack = [] max_area = 0 index = 0 while index < len(heights): if not stack or heights[index] >= heights[stack[-1]]: stack.append(index) index += 1 else: top_of_stack = stack.pop() width = index if not stack else index - stack[-1] - 1 max_area = max(max_area, heights[top_of_stack] * width) while stack: top_of_stack = stack.pop() width = index if not stack else index - stack[-1] - 1 max_area = max(max_area, heights[top_of_stack] * width) return max_area ``` 这段代码通过不断调整栈的状态以及利用宽度和高度的关系,能够高效地找到最大的矩形面积[^4]。 #### C++ 实现代码 这里也提供了一个类似的 C++ 本实现: ```cpp #include <iostream> #include <stack> #include <vector> using namespace std; int largestRectangleArea(vector<int>& heights) { stack<int> st; int maxA = 0; int n = heights.size(); for(int i = 0; i <= n; ++i){ int h = (i == n ? 0 : heights[i]); if(st.empty() || h >= heights[st.top()]) st.push(i); else{ int tp = st.top(); st.pop(); maxA = max(maxA, heights[tp]*(st.empty()?i:(i-st.top()-1))); --i; } } return maxA; } int main(){ vector<int> height = {2, 1, 5, 6, 2, 3}; cout << "The largest Rectangle in histogram is " << largestRectangleArea(height) << endl; } ``` 此本同样遵循相同的逻辑框架,但在细节上略有不同以便更好地适应C++语法特点[^5]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值