zoukankan      html  css  js  c++  java
  • 《Largest Rectangle in a Histogram》

    非常好的一道单调栈的题。

    首先说一下单调栈,它维护的是一个单调的序列。

    如果维护递增序列,那么栈顶大于当前值时,就pop栈顶,这样之后可以发现,栈顶的元素是左边最近的小于当前值的元素。

    那么对于这道题,有一个很巧妙的转化方法:合并矩形

    图片详解可见:https://blog.csdn.net/qq_19829595/article/details/96019508

    考虑当前的栈中序列为

    1 2 3 4 5 6.

    那么合并矩形时:

    sum = 6*1.

    sum = 5*2

    sum = 4*3

    sum = 3*4

    sum = 2*5

    sum = 1*6

    最后合并为 h = 1,w = 6.

    可以发现,我们这样是在计算以栈顶位置结尾的能组成的最大矩形。

    避免一直递增最后没有比较的情况发生,我们让h[n+1] = 0,保证了最后肯定会计算。

    注意的是,如果ans = -INF,那么所以高度都为0的情况时,依旧不会算,这时可以让h[n+1] = -1。

    或者一开始ans = 0.

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef long double ld;
    typedef pair<LL,int> pii;
    const int N = 1e5+5;
    const int M = 1e6+5;
    const LL Mod = 1e9+7;
    #define rg register
    #define pi acos(-1)
    #define INF 1e9
    #define INM INT_MIN
    #define dbg(ax) cout << "now this num is " << ax << endl;
    inline LL read()
    {
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
    LL S[N],w[N],h[N];
    int main() 
    {
        int n;
        while(n = read(),n != 0)
        {
            for(int i = 1;i <= n;++i) h[i] = read();
            int top = 0;
            LL ans = 0;
            h[n+1] = 0;
            for(int i = 1;i <= n+1;++i)
            {
                if(h[i] > S[top])
                {
                    S[++top] = h[i];
                    w[top] = 1;
                }
                else
                {
                    LL width = 0;
                    while(top != 0 && S[top] > h[i])
                    {
                        width += w[top];
                        ans = max(ans,width*S[top]);
                        top--;
                    } 
                    S[++top] = h[i];
                    w[top] = width+1;
                }
            }
            printf("%lld\n",ans);
        }
        system("pause");
        return 0;
    }
    View Code
  • 相关阅读:
    VS2010-MFC(对话框:模态对话框及其弹出过程)
    VS2010-MFC(对话框:设置对话框控件的Tab顺序)
    VS2010-MFC(对话框:为控件添加消息处理函数)
    VS2010-MFC(对话框:创建对话框类和添加控件变量)
    manacher算法模板
    [洛谷P1017] 进制转换
    [洛谷P1126] 机器人搬重物
    [洛谷P1032] 字串变换
    [POI2005]SAM-Toy Cars
    [洛谷P1528] 切蛋糕
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/13418953.html
Copyright © 2011-2022 走看看