Cuelgue HDU eléctrica 1506 (fjutacm 1899) rectángulo más grande en un solo tono un histograma pila

Descripción del problema
Un histograma es un polígono compuesto por una secuencia de rectángulos alineados en una línea de base común. Los rectángulos tener iguales anchuras, pero pueden tener diferentes alturas. Por ejemplo, la figura de la izquierda muestra el histograma que consiste en rectángulos con las alturas 2, 1, 4, 5, 1, 3, 3, medida en unidades donde 1 es la anchura de los rectángulos:
Aquí Insertar imagen Descripción
Por lo general, los histogramas se utilizan para representar distribuciones discretas, por ejemplo, las frecuencias de caracteres de textos. Tenga en cuenta que el orden de los rectángulos, es decir, sus alturas, es importante. Calcular el área de la más grande rectángulo en un histograma que está alineado en la línea de base común, también. La figura de la derecha muestra el rectángulo más grande Alineados para el histograma representado.题意很简单就是找直方图能嵌套的最大矩形

Entrada
La entrada contiene varios casos de prueba. Cada caso de prueba describe un histograma y se inicia con un número entero n, que indica el número de rectángulos que lo componen. Es posible suponer que 1 <= n <= 100000. A continuación, siga n enteros H1, ..., hn, donde 0 <= hi <= 1000000000. Estos números indican las alturas de los rectángulos del histograma de la izquierda a la derecha orden. La anchura de cada rectángulo es 1. Un cero sigue a la entrada para el último caso de prueba.

Salida
Para cada caso de prueba de salida en una sola línea del área del rectángulo más grande en el histograma especificado. Recuerde que este rectángulo debe estar alineado en la línea de base común.

SampleInput
7 2 1 4 5 1 3 3
4 1,000 1,000 1,000 1,000
3 2 1 2
0

SampleOutput
8
4.000
3

Sí, el significado de las preguntas es simplemente encontrar los más grandes, secciones rectangulares continuos.

Así que antes de empezar, primero limpiar queremos mantener una pila monótona creciente. ¿Por qué? Mediante la simulación de unos pocos casos simples encontramos que cuando la altura de una caja superior a los dos lados, es imposible ir hacia abajo en ambos lados de la expansión.

Por lo tanto, si tenemos que mantener una pila monótona, entonces cada vez que mantenemos esta pila, sólo se necesita hacer un ciclo de funcionamiento de la pila, y actualizar fácilmente la respuesta. Por último tenemos la monotonía o una pila, esta vez al final para poner un número suficiente de, por una sola vez pequeña empujó hacia atrás, mientras que la pila mientras se actualiza la respuesta, la solución se obtiene finalmente.

No puedo decir el texto, combinado con una mejor comprensión del código y la caja.

#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;
}

Este caso es aún muy cuestión a tener una conciencia, pensamiento y más de acuerdo con el código, o la pila monótona, para simular un par de veces e inmediatamente ser capaz de entender cómo mantener, que detalla el mantenimiento tiene.

Se han publicado 19 artículos originales · ganado elogios 0 · Vistas 502

Supongo que te gusta

Origin blog.csdn.net/qq_43317133/article/details/99638331
Recomendado
Clasificación