zoukankan      html  css  js  c++  java
  • HDU 1506 Largest Rectangle in a Histogram(单调栈)

    题目链接

    题目大意

      给一个直方图,在图中取一个矩形,使其面积最大。

    解题思路1

      显然对于一个选定的矩形(S)来说,其高度取决于所选的直方图矩形中高度最低的那个矩形(a_i),换句话说,在选定的面积(S)内对于这个高度最低的矩形(a_i)来说,没有比它更低的矩形了。所以我们可以用一个矩形,看它能向左向右扩展到哪里,就能得到包括这个矩形(a_i)的最大面积(S)。至于选定区间的左右端点,可以用单调栈来求出,方法与这道题类似。

    代码1

    const int maxn = 1e5+10;
    int n, arr[maxn], l[maxn], r[maxn];
    stack<int> sk, clears;
    int main(void) {
        while(~scanf("%d",&n) && n) {
            for (int i = 1; i<=n; ++i) scanf("%d",&arr[i]);
            for (int i = 1; i<=n; ++i) {
                while(!sk.empty() && arr[sk.top()]>=arr[i]) sk.pop(); //栈顶是小于当前元素的第一个数的下标
                l[i] = sk.empty() ? 1 : sk.top()+1; //因为不包括小于当前元素的数所以右移一个坐标
                sk.push(i);
            }
            sk = clears;
            for (int i = n; i>=1; --i) {
                while(!sk.empty() && arr[sk.top()]>=arr[i]) sk.pop(); //同上
                r[i] = sk.empty() ? n : sk.top()-1; //因为不包括小于当前元素的数所以左移一个坐标
                sk.push(i);
            }
            sk = clears;
            ll ans = 0;
            for (int i = 1; i<=n; ++i) ans = max(ans, (ll)arr[i]*(r[i]-l[i]+1));
            printf("%lld
    ",ans);
        }
        return 0;
    }
    

    解题思路2

      依然使用单调栈。对于一个连续递增的矩形,很明显,以每个子矩形能够形成的宽度就是他前面的宽度加上他自己的宽度。如果往右边加入一个较低的矩形破坏其单调性,那么这个较低矩形可以形成的宽度就是最左边的比他高的矩形到他的宽度,将中间的矩形弹出,栈依旧具有单调性。

    代码2

    const int maxn = 1e5+10;
    int n, arr[maxn];
    stack<P> sk, clears;
    int main(void) {
        while(~scanf("%d",&n) && n) {
            for (int i = 1; i<=n; ++i) scanf("%d",&arr[i]);
            ll ans = 0;
            arr[n+1] = 0; //用于清空前面的数
            for (int i = 1; i<=n+1; ++i) {
                int w = 0;
                while(!sk.empty() && arr[sk.top().first]>=arr[i]) {
                    w += sk.top().second;
                    ans = max(ans, (ll)arr[sk.top().first]*w);
                    sk.pop(); 
                }
                sk.push({i,w+1});
            }
            sk = clears;
            printf("%lld
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    Codeforces 1491 D. Zookeeper and The Infinite Zoo (二进制处理)
    Codeforces 1479A. Searching Local Minimum(注意输入+二分)
    Codeforces 1480B. The Great Hero(阅读模拟题,注意数据范围和攻击顺序)
    Codeforces 1480A. Yet Another String Game (阅读理解题)
    windows 10 开启全盘瞬间索引功能
    JetBrains CLion C++ IDE连接wsl2(Ubuntu)时,报错"Unable to establish SSL connection"解决方案
    WorkFlowy 的 MarkDown 预览方案解决
    git 学习 完全学懂
    jeecgboot <j-popup
    面试之类加载器
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/12723454.html
Copyright © 2011-2022 走看看