zoukankan      html  css  js  c++  java
  • POJ2559 Largest Rectangle in a Histogram 题解 单调队列/单调栈 (直方图的最大矩形面积)

    题目链接:http://poj.org/problem?id=2559

    题目大意:
    直方图中的每一个柱子都是一个宽度为 (i) 高度为 (h_i) 的矩形,求最大矩形面积。

    解题思路:
    定义两个数组:

    • (L[i]) 表示第 (i) 根柱子往左走碰到的第一根比它矮的柱子的坐标 (+1)(如果第 (i) 根柱子左边的柱子没有比它矮的,则 (L[i] = 1));
    • (R[i]) 表示第 (i) 根柱子往右走碰到的第一根比它矮的柱子的坐标 (-1)(如果第 (i) 根柱子右边的柱子没有比它矮的,则 (R[i] = n))。

    然后从左到右遍历每个坐标,并且维护一个 (h_i) 单调递增的单调队列,则 (i) 入队列前,队尾元素对应的坐标就是 (L[i]-1)(若此时队列为空则 (L[i]=1))。

    然后从右往左遍历每个坐标,并且维护一个 (h_i) 单调递增的单调队列,则 (i) 入队列前,队尾元素对应的坐标就是 (R[i]+1)(若此时队列为空则 (R[i]=n))。

    实现代码如下:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <deque>
    using namespace std;
    const int maxn = 100010;
    int n, L[maxn], R[maxn];
    long long h[maxn], ans;
    deque<int> que;
    int main() {
        while (~scanf("%d", &n) && n) {
            for (int i = 1; i <= n; i ++) scanf("%lld", h+i);
            que.clear();
            for (int i = 1; i <= n; i ++) {
                while (!que.empty() && h[que.back()] >= h[i]) que.pop_back();
                if (!que.empty()) L[i] = que.back()+1;
                else L[i] = 1;
                que.push_back(i);
            }
            que.clear();
            for (int i = n; i >= 1; i --) {
                while (!que.empty() && h[que.back()] >= h[i]) que.pop_back();
                if (!que.empty()) R[i] = que.back()-1;
                else R[i] = n;
                que.push_back(i);
            }
            ans = 0;
            for (int i = 1; i <= n; i ++)
                ans = max(ans, (R[i]-L[i]+1) * h[i]);
            printf("%lld
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    hdu1251统计难题(trie树)
    线段树
    poj2632Crashing Robots
    UVA10194 Football (aka Soccer)
    hdu1166敌兵布阵(线段树)
    【洛谷P3810】【模板】三维偏序(陌上花开)
    【洛谷P2480】古代猪文
    【洛谷P3449】PALPalindromes
    【洛谷P4777】扩展中国剩余定理(EXCRT)
    【洛谷P2421】荒岛野人
  • 原文地址:https://www.cnblogs.com/quanjun/p/12297093.html
Copyright © 2011-2022 走看看