zoukankan      html  css  js  c++  java
  • 51Nod 1102 面积最大的矩形 +1272 最大距离 单调栈

    51Nod 1102 面积最大的矩形

    记笔记记笔记:对于区间最值与区间长度/和等的问题,用单调栈来维护区间端点。

    这里来补一补单调栈和单调队列的基础知识:

    单调栈:                                        //单调递增(减)栈:从栈顶到栈底为单调递增(减)

           单调栈解决的是以某一值为区间最值的最大区间的问题,实现方法:维护一个单调递增(减)的栈,当遇到比栈顶元素大(小)的元素准备入栈时,开始跳栈,直到栈顶元素大于(小于)当前元素。跳栈结束后开始更新当前元素的区间(无论是否有跳栈操作,都要更新区间)。

    单调队列:

           单调队列解决的是区间最值的问题,实现方法:维护一个单调递增(减)的双端队列,队列中保存原始序列的标号,当将要入队的元素比队尾元素小(大)时,队尾开始出队,直至当前元素大于(小于)队尾元素,当入队元素与队首元素跨度大于规定区间时,队首开始出队,直至符合区间要求。可以保证队首元素为区间最小(大)值,但不能保证队尾为原始序列中的最大(小)值,同时维护了区间长度。

    #include<iostream> //这里用的是单调递减栈
    #include<string>
    #include<algorithm>
    #include<stack>
    using namespace std;
    struct squre{
        long long l,r,h;
    };
    stack<squre>a;
    int n;
    squre b,c,ans[50005];
    int main()
    {
        cin >> n;
        if (n == 0)
            cout << "0" << endl;
        else
        {
            int cnt = 0;
            cin>>b.h;
            b.l = 0; b.r = 1;
            a.push(b);
            for (int i = 1; i < n; i++)
            {
                c.h=0;            //记录是否更新栈顶元素
                cin >> b.h;
                while (!a.empty() && a.top().h > b.h)  //准备入栈元素高度<栈顶元素,出栈
                {
                    a.top().r=i;
                    ans[cnt++] = a.top();             //记录区间无法继续延伸的元素
                    c = ans[cnt - 1];
                    a.pop();
                }
                if (c.h != 0)               //更新当前元素区间
                {
                    b.l = !a.empty() && a.top().h == b.h ? a.top().l : c.l;
                }
                else
                {
                    b.l = !a.empty() && a.top().h == b.h ? a.top().l : i;
                }
                b.r = i + 1;
                a.push(b);
            }
            while (!a.empty())   //全部出队
            {
                a.top().r = n;
                ans[cnt++] = a.top();
                a.pop();
            }
            long long res = 0;
            for (int i = 0; i < n; i++)  //记录面积最大值
            {
                res = max(res, ans[i].h*(ans[i].r - ans[i].l));
            }
            cout << res << endl;
        }
        return 0;
    }

     1272 最大距离 

    相对上面的题,这个题要简单很多,用一个单调栈来维护最大区间,一个栈来保存跳栈的数据,每次跳栈的时候记录一下,数据处理完重新入栈。

     //有毒……这个题……#21一直TLE,orz ……有米有大佬指点一下

    #include<iostream>
    #include<string>
    #include<stack>
    #include<algorithm>
    using namespace std;
    struct node {
        int v, id;
    };
    stack<node>save, now;
    int main()
    {
        int n;
        cin >> n;
        int ans = 0;
        for (int i = 1; i <= n; i++)
        {
            node a;
            a.id = i;
            cin >> a.v;
            if (now.size()==0 || a.v < now.top().v)
                now.push(a);
            else
            {
                while (!now.empty()&&now.top().v <= a.v)
                {
                    ans = max(ans, i - now.top().id);
                    save.push(now.top());
                    now.pop();
                }
                while (!save.empty())
                {
                    now.push(save.top());
                    save.pop();
                }
            }
        }
        cout << ans << endl;
        return 0;
    }
  • 相关阅读:
    利用密钥通过ssh互访
    rsync参数及通信
    cacti 安装
    地区排名脚本 一千三百多行代码
    调用分隔符的数组。
    select case when
    jquery 设置select 默认值
    常见的分析函数
    oracle分析函数 之分组累加求和
    ORACLE的表被 另一个用户锁定,如何解除..
  • 原文地址:https://www.cnblogs.com/Egoist-/p/7718961.html
Copyright © 2011-2022 走看看