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;
    }
    
  • 相关阅读:
    查找并拷贝目录中指定文件到某个文件夹
    TPS和QPS的概念
    50道 Redis常见面试题,干货汇总
    面试题:写一个死锁示例
    MySQL聚集索引与辅助索引的区别
    Java进阶知识点:接口幂等性
    测试网络联接状况常用命令 ping 使用方法介绍
    服务路由、负载均衡和服务配置中心的基本概念
    利用堆排序和分治法求解千万级数据排序的Top K问题—百度面试
    创建Spring Boot项目时,提示 Cannot download 'https://start.spring.io'
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/12723454.html
Copyright © 2011-2022 走看看