• 关于POJ2559 Largest Rectamgle in Histogram的几个不同解法


    单调栈1

    使用单调栈,合并矩形然后再加入新矩阵。

    # include <bits/stdc++.h>
    using namespace std;
    const int N = 100005;
    int n;
    long long h[N],w[N];
    long long ans = 0;
    stack <pair<long long,long long> > s; // {w,h}
    int main(void)
    {
        while(~scanf("%d",&n) && n)
        {
            for(int i = 1; i <= n; i++)
            {
                scanf("%d",&h[i]);
                w[i] = 1;
            }
            w[n + 1] = 0;
            h[n + 1] = 0;
            ans = 0;
            while(!s.empty()) s.pop();
            s.push(make_pair(1,h[1]));
            for(int i = 2; i <= n + 1; i++)
            {
                if(s.empty())
                {
                    s.push(make_pair(1,h[i]));
                    continue;
                }
                if(s.top().second <= h[i])
                {
                    s.push(make_pair(1,h[i]));
                }
                else
                {
                    long long totw = 0;
                    while(!s.empty() && s.top().second > h[i])
                    {
                        totw += s.top().first;
                        ans = max(ans,s.top().second * totw);
                        s.pop();
                    }
                    s.push(make_pair(totw,h[i]));
                }
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    

    单调栈2

    使用;两次单调栈,求出(l_i,r_i)(l_i)表示从(i)往左的每一个(h_j <= h_i)的最远位置,即(min{x mid forall_{b ge x} a_b ge a_i}),(r_i)同理。

    # include <bits/stdc++.h>
    using namespace std;
    
    # define int long long
    
    const int N = 100010;
    
    int n;
    int h[N];
    int l[N],r[N];
    stack <pair<int,int> > s;
    signed main(void)
    {
        while(~scanf("%lld",&n) && n)
        {
            while(!s.empty()) s.pop();
            for(int i = 1; i <= n; i++)
                {
                    scanf("%lld",&h[i]);
                }
                for(int i = 1; i <= n; i++)
                {
                    while(!s.empty() && s.top().first >= h[i]) s.pop();
                    if(!s.empty()) l[i] = s.top().second + 1;
                    else l[i] = 1;
                    s.push(make_pair(h[i],i));
                }
                while(!s.empty()) s.pop();
                for(int i = n; i >= 1; i--)
                {
                    while(!s.empty() && s.top().first >= h[i]) s.pop();
                    if(!s.empty()) r[i] = s.top().second - 1;
                    else r[i] = n;
                    s.push(make_pair(h[i],i));
                }
            long long ans = 0;
                for(int i = 1; i <= n; i++)
                {
                    ans = max(ans,(long long)h[i] * 1ll * (r[i] - l[i] + 1));
                }
            printf("%lld
    ",ans);
        }
        
        return 0;
    }
    

    笛卡尔树

    这个不讲了,不过是完全可做的。

  • 相关阅读:
    数据压缩API
    Dll劫持
    傀儡进程
    自定义网页右键菜单总结
    自定义checkbox, radio样式总结
    有趣的鼠标悬浮模糊效果总结
    听指令的小方块(二)总结
    听指令的小方块(一)总结
    表单(三)联动总结
    表单(二)多个表单项的动态校验总结
  • 原文地址:https://www.cnblogs.com/luyiming123blog/p/14221002.html
Copyright © 2020-2023  润新知