zoukankan      html  css  js  c++  java
  • 笔记——单调队列&&单调栈优化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[][][][]..[]= ....
    

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

  • 相关阅读:
    对康托展开的一些心得...
    HDUOJ-----Computer Transformation
    hduoj1073--Online Judge
    HDUOJ 2672---god is a girl 《斐波那契数》
    南阳OJ----Binary String Matching
    HDUOJ--汉诺塔II
    <五>企业级开源仓库nexus3实战应用–使用nexus3配置npm私有仓库
    <六>企业级开源仓库nexus3实战应用–使用nexus3配置yum私有仓库
    <三>企业级开源仓库nexus3实战应用–使用nexus3配置maven私有仓库
    filebeat安装配置
  • 原文地址:https://www.cnblogs.com/resftlmuttmotw/p/11323300.html
Copyright © 2011-2022 走看看