您的位置:首页 > 其它

POJ2559 HDU1506 ZOJ1985 Largest Rectangle in a Histogram【堆栈+水题】

2017-03-12 20:23 393 查看
Largest Rectangle in a Histogram

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 23297 Accepted: 7547
Description
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.
Source
Ulm Local 2003

问题链接:POJ2559 HDU1506 ZOJ1985 Largest Rectangle in a Histogram

问题描述:参见上文。

问题分析

  解决这个问题,一种是用暴力法(枚举法)来解决,任何一个矩形必然始于第i个直方图,终止于第j块直方图(i<=j),从所有这些面积中找出最大矩形面积即可;另外一种办法是对这n个数只看一遍,就算出最大矩形面积,其计算复杂度为O(n),相比较而言,算法要复杂一些,需要付出一些空间的代价。

程序说明

  本程序采用后一种方法实现。基本思想是先找到一个逐步递增的面积,即如果Hi<Hi+1则最大面积是逐步递增的。这个过程中,将这些Hi放入堆栈中,直到不满足Hi<Hi+1为止。这个时候,最大的面积可能是最右边是Hi,由若干块(也可能只有1块)拼成的,从中获得一个最大的面积。出现面积非递增时,则把堆栈中比当前高的直方图弹出,重复上述过程,需要说明的是这不影响高的直方图与其右边连成一片。还有一点就是,所有的直方图的高度Hi>=1,这是一个前提,如果有的直方图高度为0,则这个算法需要另外设计。

参考链接:CCF201312-3
最大的矩形(100分)。

AC的C++语言程序如下:

/* POJ2559 HDU1506 ZOJ1985 Largest Rectangle in a Histogram */

#include <iostream>
#include <cstdio>
#include <stack>

using namespace std;

const int MAXN = 100000;

long long h[MAXN+1];

int main()
{
int n, temp;
long long ans, area;

while(scanf("%d", &n) != EOF && n) {
// 输入数据
for(int i=0; i<n; i++)
scanf("%lld", &h[i]);
h
= 0;

// 计算最大矩形面积
ans = 0;
stack<int> s;
for(int i=0; i<=n; i++) {
if (s.empty() || h[s.top()] < h[i])
s.push(i);
else {
temp = s.top();
s.pop();            //弹出
area = h[temp] * (s.empty() ? i : i - s.top() - 1);
if (area > ans)
ans = area;
--i;
}
}

// 输出结果
printf("%lld\n", ans);
}

return 0;
}

TLE的C++语言程序如下:

/* POJ2559 HDU1506 ZOJ1985 Largest Rectangle in a Histogram */

#include <iostream>
#include <cstdio>

using namespace std;

const int MAXN = 100000;

long long h[MAXN];

int main()
{
int n;
long long ans, height, area;

while(scanf("%d", &n) != EOF && n) {
// 输入数据
for(int i=0; i<n; i++)
scanf("%lld", &h[i]);

// 计算最大矩形面积:暴力法(枚举法)
ans = 0;
for(int i=0; i<n; i++) {
height = h[i];
for(int j=i; j<n; j++) {
if(h[j] < height)
height = h[j];
area = (j - i + 1) * height;
if(area > ans)
ans = area;
}
}

// 输出结果
printf("%lld\n", ans);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: