题目如下:
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.
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.
题目分析:单调栈的模板题,关于单调栈,其实适用于求解最小值的最大区间以及最大值的最大区间。对于这一题而言要求直线上的最大矩形和,而且要是一段以一段上的最小高度来计算。很明显是一道最小值的最大区间的模型题。
做法:对于最小值的最大区间问题,首先用单调栈维护递增序列。如果发现一个当前值小于栈顶元素,就弹栈直到栈顶元素小于等于当前元素或者栈空。然后我们要累积的和就是我们弹出来的这些元素。用一个minval维护这些元素中的最小值并且用lsum维护这些元素的总宽度。用sum维护最终结果。但是要注意的是sum的维护是要在每次弹出一个元素的时候就进行。即:每弹出一个元素就要进行一次sum的更新。原因可能这一个弹出的元素远远大于其他的。可能这一个元素的高度就比其他所有的和都要大。
代码入下:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<stack>
using namespace std;
const int maxx = 100000 + 50;
int n, aa;
struct My {
long long w, h;
My() {}
My(int a, int b): w(a), h(b) {}
} x;
stack<My>sta;
int cun[maxx];
int main() {
while(scanf("%d", &n) != EOF) {
if(n == 0)break;
while(!sta.empty())sta.pop();
x.w = x.h = 0;
sta.push(x);
long long sum = -1, lsum = 0, minval = 1LL << 34;
for(int i = 0; i < n; i++) {
scanf("%lld", &x.h); x.w = 1;
if(x.h >= sta.top().h) {
sta.push(x);
} else {
minval = 1LL << 34; lsum = 0;
while(!sta.empty()) {
if(sta.top().h <= x.h)break;
lsum += sta.top().w;
minval = min(minval, sta.top().h);
sum = max(sum, lsum * minval);
sta.pop();
}
sta.push(My(lsum, minval));
sta.push(x);
}
}
lsum = 0; minval = 1LL << 34;
while(!sta.empty()) {
lsum += sta.top().w;
minval = min(minval, sta.top().h);
sum = max(sum, lsum * minval);
sta.pop();
}
printf("%lld\n", sum);
}
return 0;
}