zoukankan      html  css  js  c++  java
  • 「题解」洛谷 SP1805 HISTOGRA

    题目

    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
    ", 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
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    HDU 1882 Strange Billboard(位运算)
    Codeforces Round #243 (Div. 2) A~C
    Codeforces Round #242 (Div. 2) A~C
    2014 微软 编程之美初赛第一场 题目3 : 活动中心
    2014年微软编程之美初赛第一场 第二题 树
    POJ 2318 TOYS && POJ 2398 Toy Storage(几何)
    Coder-Strike 2014
    POJ 1269 Intersecting Lines(几何)
    HDU 1883 Phone Cell (圆覆盖最多点)
    HDU 1429 胜利大逃亡(续)(三维BFS)
  • 原文地址:https://www.cnblogs.com/poi-bolg-poi/p/13650354.html
Copyright © 2011-2022 走看看