Hang HDU electric 1506 (fjutacm 1899) Largest Rectangle in a Histogram stack monotone

Problem 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:
Here Insert Picture Description
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.

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

SampleOutput
8
4000
3

Yes, the meaning of the questions is simply to find the largest, continuous rectangular sections.

So before you start, first clear we want to maintain a monotonic increasing stack. why? By simulating a few simple cases we find that when the height of a box higher than both sides, it is impossible to go down on both sides of the expansion.

So, if we have to maintain a monotonous stack, then each and every time we maintain this stack, only need to do a cycle of operation of the stack, and easily update the answer. Finally we get monotony or a stack, this time at the end to put a sufficient number of small, one-time pushed back, while the stack while updating the answer, the solution is finally obtained.

I can not tell text, combined with a better understanding of the code and case.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <stack>
#include <queue>
#include <vector>
using namespace std;
const int MAX=1e5+5;
typedef long long ll;
typedef unsigned long long ull;
struct node
{
  ll h, w;/// h记录高度,w记录连续区间长度
}q[MAX], a;
int main()
{
  ll n, h, i, j, ans, top, last;
  while (scanf("%I64d", &n)&&n)
  {
    ans = top = 0;/// 初始化,栈一开始是空的,所以栈首位置top在0处
    memset(q, 0, sizeof(q));
    for (i=0; i<n; i++)
    {
      scanf("%I64d", &q[top].h);
      q[top].w = 0;/// 为了不影响维护单调栈、top往前推的操作,刚推入栈的元素
                   ///的w我们先初始化为0

      while (top&&q[top].h<=q[top-1].h)/// top不能为0,前面没元素就没必要维护;
      {                                ///维护单调递增,所以后一个元素小于前一
                                       ///个元素时,我们就需要更新维护了(=可
                                       ///有可无)
        q[top-1].w += q[top].w;/// 因为是单调栈,所以当前元素一定可以扩张到栈
                               ///首。比如案例中,假设我们维护到栈为 1 4 5 了,
                               ///这时候5能向后扩张0个,4能向后扩张5的w个,也
                               ///就是1个,1能想后扩张4的w个,也就是1+1个。所
                               ///以这一轮如果我们直接在5后面放个0一次性推到
                               ///底,我们能得到5*1,4*2和1*3这三个答案
/// w说得更明白一点,就是压入你这个元素时,有多少个元素出栈了。这意味着,这
///个元素“吃”掉了那么多个比它大的元素,纳入了自己的可扩张区间。毕竟只要前面
///的元素大于(等于)当前元素,就说明以当前元素的高度还可以往前继续扩张
        ans = max(ans, q[top-1].h*q[top-1].w);
        q[top-1].h = q[top].h;
        top --;
      }
      q[top].w ++;
      top ++;
    }
    q[top].h = 0;/// 最后一次大清仓,把栈中余下元素能产生的答案全部生成出来,
    q[top].w = 0;///更新解。这里的操作就是直接压入一个恒小于所有栈中元素的新
                 ///元素0,保证它能一路往回推
    while (top&&q[top].h<=q[top-1].h)
    {
      q[top-1].w += q[top].w;
      ans = max(ans, q[top-1].h*q[top-1].w);
      q[top-1].h = q[top].h;
      top --;
    }
    printf("%I64d\n", ans);
  }
  return 0;
}

This case is still very question to have a conscience, thinking and more in accordance with the code, or the monotonous stack, to simulate a few times and immediately be able to understand how to maintain, which details the maintenance have.

Published 19 original articles · won praise 0 · Views 502

Guess you like

Origin blog.csdn.net/qq_43317133/article/details/99638331