hdu1506 Largest Rectangle in a Histogram

本文深入探讨了计算直方图中最大矩形面积的高效算法。通过双向判断,算法以每个矩形高度为中心,向左右两侧扩展,直到遇到比当前高度小的矩形为止。利用栈辅助计算可延伸范围,最终得出所有可能的最大矩形面积,适用于解决直方图分布问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目
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

  1. 双向判断,以当前高度向左向右延伸(当左边高度大于等于当前高度时向左延伸,l数组记录向左延伸到哪里;当右边高度大于等于当前高度时向右延伸,r数组记录向右延伸到哪里),最右减最左再乘以当前高度就是该高度的最大面积
  2. 此代码中设st数组为栈,设栈中元素从上到下的值为xi>xi+1且 hxi>hxi+1(我实在是不会在这里面输入下标啊),st数组帮助判断可以向左或向右延伸多少(这里很重要,要好好理解一下)
  3. 代码来源于《挑战程序设计竞赛》
#include <stdio.h>
#include <string.h>
#include <stack>
#include <algorithm>
using namespace std;
int n,h[100010],l[100010],r[100010],st[100010];
void solve()
{
	int t=0;
	for(int i=0;i<n;i++)  //计算l数组
	{
		while(t>0&&h[st[t-1]]>=h[i]) 
		    t--;
		l[i]=t==0?0:(st[t-1]+1);  //t==0,栈为空,左边高度均大于等于当前元素的高度,可以延伸到最左边,否则根据st数组计算可以延伸的长度
		st[t++]=i;
	}
	t=0;
	for(int i=n-1;i>=0;i--)  //计算r数组
	{
		while(t>0&&h[st[t-1]]>=h[i])
		    t--;
		r[i]=t==0?(n-1):(st[t-1]-1);
		st[t++]=i;
	}
	long long c=0;
	for(int i=0;i<n;i++)
	    c=max(c,(long long)h[i]*(r[i]-l[i]+1));  //加1是因为要加上他自己,否则只有左边的和右边的
	printf("%lld\n",c); 
}
int main()
{
	while(scanf("%d",&n)!=EOF&&n)
	{
		for(int i=0;i<n;i++)
		    scanf("%d",&h[i]);
		solve();
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值