「题解」洛谷 SP1805 HISTOGRA - Largest Rectangle in a Histogram

题目

SP1805 HISTOGRA - Largest Rectangle in a Histogram

简化题意

给以一个每个矩形宽都是 \(1\) 的直方图,让你求其中最大的矩形面积

思路

单调栈,悬线法。

对于每个矩形求出以这个矩形的高度为高的且包含这个矩形的大矩形最左边和最右边是哪。

单调栈/悬线法板子题。

Code

悬线法:

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define M 100001

typedef long long ll;
ll max(ll a, ll b) { return a > b ? a : b; }

ll ans;
int n, l[M], r[M], a[M];

inline void read(int &T) {
    int x = 0;
    bool f = 0;
    char c = getchar();
    while (c < '0' || c > '9') {
        if (c == '-') f = !f;
        c = getchar();
    }
    while (c >= '0' && c <= '9') {
        x = x * 10 + c - '0';
        c = getchar();
    }
    T = f ? -x : x;
}

int main() {
    while (1) {
        ans = 0, read(n);
        if (!n) break;
        for (int i = 1; i <= n; ++i) {
            read(a[i]);
            l[i] = r[i] = i;
        }
        for (int i = 1; i <= n; ++i) {
            while (l[i] > 1 && a[i] <= a[l[i] - 1]) l[i] = l[l[i] - 1];
        }
        for (int i = n; i >= 1; --i) {
            while (r[i] < n && a[i] <= a[r[i] + 1]) r[i] = r[r[i] + 1];
        }
        for (int i = 1; i <= n; ++i) {
            ans = max(ans, 1ll * (r[i] - l[i] + 1) * a[i]);
        }
        printf("%lld\n", ans);
    }
    return 0;
}

单调栈:

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define M 100518

long long max(long long a, long long b) { return a > b ? a : b; }

long long ans;
int n, top, a[M], w[M], s[M];

int main() {
    while (scanf("%d", &n) != EOF && n) {
        ans = 0, top = 0;
        for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
        a[n + 1] = 0, s[++top] = a[1], w[1] = 1;
        for (int i = 2; i <= n + 1; ++i) {
            if (s[top] < a[i]) {
                s[++top] = a[i];
                w[top] = 1;
            }
            else {
                int len = 0;
                while (top && s[top] >= a[i]) {
                    len += w[top];
                    ans = max(ans, 1ll * len * s[top]);
                    --top;
                }
                s[++top] = a[i], w[top] = len + 1;
            }
        }
        printf("%lld\n", ans);
    }
    return 0;
}
posted @ 2020-09-11 10:46  yu__xuan  阅读(135)  评论(0编辑  收藏  举报