• 【POJ 2559】Largest Rectangle in a Histogram【栈】


    题目大意:

    题目链接:http://poj.org/problem?id=2559
    给出一个直方图,在不超过其边界且要求底边和高分别平行于第和最左边直方图的高的情况下,找到其中的最大面积长方形。
    本题由多组数据。


    思路:

    思路一:
    先枚举每一个直方图,再直接暴力左右扩展边界,直到无法扩展为止。时间复杂度O(t×n2),十分不优秀。


    思路二:
    先用ST求出每个区间的最小值,然后再枚举每一个直方图,利用最小值求出左右边界。时间复杂度$O(t\times nlogn),依旧不优秀。


    思路三:
    考虑利用栈并且保持栈的单调性,当h[s.top()]>a[i]时,就不断pop掉,并求出最大值。时间复杂度O(tn),优秀。

    while (q.size()&&a[q.top()]>a[i])
    {
            sum+=b[q.top()];    
            ans=max(ans,sum*a[q.top()]);
            q.pop();
    }   

    代码:

    #include <cstdio>
    #include <stack>
    #include <iostream>
    #include <cstring>
    #define N 100100
    using namespace std;
    
    long long ans,sum,a[N+1],b[N+1];
    int n;
    stack<long long> q;
    
    int main()
    {
        while (1)
        {
            memset(a,0,sizeof(a));
            memset(b,0,sizeof(b));
            ans=sum=0;  
            while (q.size()) q.pop(); //初始化
            scanf("%d",&n);
            if (!n) return 0;
            for (int i=1;i<=n;i++)
            {
                scanf("%lld",&a[i]);
            }
            q.push(1); 
            b[1]=1;  //先将第一个图放入栈
            for (int i=2;i<=n+1;i++)
            {
                if (q.size()&&a[q.top()]<=a[i])  //保持单调
                {
                    q.push(i);
                    b[i]=1;  //宽度
                }
                else
                {
                    sum=0;
                    while (q.size()&&a[q.top()]>a[i])  //不单调
                    {
                        sum+=b[q.top()];  //增加宽度
                        ans=max(ans,sum*a[q.top()]);
                        q.pop();
                    }   
                    q.push(i);
                    b[q.top()]=sum+1;  //宽度
                }
            } 
            cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    【洛谷P2839】middle
    【洛谷P2495】消耗战
    【CF1438D】Powerful Ksenia
    【CF878E】Numbers on the blackboard
    【洛谷U138580】简单的打击
    【洛谷P4774】屠龙勇士
    【GMOJ5363】生命之树
    【YbtOJ#20075】区间异或
    【YbtOJ#20077】计划带师
    hdu 2688
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998746.html
Copyright © 2020-2023  润新知