• 笔记——单调队列&&单调栈优化DP


    众所周知

    我csdn的博客

    动态规划 的 题

    往往 推了a long time
    但是o(n^3)
    于是就自闭了

    所以我们有了

    单调队列和栈

    这种东西

    神奇的单调队列

    有这么一道题

    朴素 o(n^2)

    乱搞 o(nlog n)(线段树、RMQ)

    然后。。。

    单调队列
    o(n)

    对,你没有看错,

    就是一遍 其实是o(2n)?!

    单调队列

    用一个东西(栈、队列、数组。。。随君所好)

    然后,

    解释都在注释里

    #include <cstdio>
    using namespace std;
    const int MAXN = 1000001;
    int num[MAXN],q[MAXN],it[MAXN],q1[MAXN],it1[MAXN];
    /*要求最大和最小,q-min,q1-max
    it&&it1记录q和q1中元素原来所在位置
    num记录读入的值
    */
    int ALL,Begin,End,Begin1,End1,pr[MAXN];
    /*
    ALL充当二次输出的Index,pr则记录二次输出的值
    Begin,End记录q的队首&&队尾
    Begin1,End1记录q1的队首&&队尾
    */
    int main()
    {
        int n,k,i;
        scanf("%d%d",&n,&k);
        for(i = 1;i <= n;i++)
            scanf("%d",&num[i]);
        //读入
        for(i = 1;i <= n;i++)
        {
            if(Begin == 0)
            {
                ++Begin,++End;
                q[Begin] = num[i];
                it[Begin] = i;
                ++Begin1,++End1;
                q1[Begin1] = num[i];
                it1[Begin1] = i;
                //其实上面这一步无必要
            } else {
                while(q[End] >= num[i]&&End >= Begin)
                    --End;
                /*当q的队尾元素大于此时要处理的num[i]
                因为q-min
                所以此时q的队尾元素以后绝不会再用到
                */
                End++;
                //加之前的End是不满足q[End] >= num[i]&&End >= Begin
                q[End] = num[i];
                it[End] = i;
                //记录对应的值
                while(q1[End1] <= num[i]&&End1 >= Begin1)
                    --End1;
                End1++;
                q1[End1] = num[i];
                it1[End1] = i;
                //同求MIN,符号 反一下
            }
            //这样处理后q的队首一定min,q1一定max
            if(i >= k)
            {
            	//符合题意,可以输出了
                while(it[Begin] < i - k + 1)
                    Begin++;
                   //如果q此时队头不在范围中
                while(it1[Begin1] < i - k + 1)
                    Begin1++;
                    //同上
                ALL++;
                //记录二次输出的值
                pr[ALL] = q1[Begin1];
                printf("%d ",q[Begin]);
            }
        }
        putchar('
    ');
        //putchar常数优化,然而并没有什么用
        for(i = 1;i <= ALL;i++)
            printf("%d ",pr[i]);
    }
    
    

    又一道稍微难一点的题

    Max Sum of Max-K-sub-sequence

    单调队列与dp的关系

    一道例题
    瑰丽华尔兹
    在一个状态转移方程中

    dp[][][][]..[]= ....
    

    在一定条件下可以将最后一维压缩成单调队列

  • 相关阅读:
    perl linux 编译成可执行程序
    MQSeries::Message 面向对象接口的MQSeries messages
    数据化管理第一步,你真的会做报表吗?
    数据化管理第一步,你真的会做报表吗?
    aix ipcs 官方解释
    使用jquery.qrcode生成二维码及常见问题解决方案
    案例分享|某医药集团的BI建设案例
    aix ipcs OxFFFFFFFF
    案例分享|某医药集团的BI建设案例
    地图应用之 :获取当前位置的经纬度
  • 原文地址:https://www.cnblogs.com/resftlmuttmotw/p/11323300.html
Copyright © 2020-2023  润新知