zoukankan      html  css  js  c++  java
  • 单调队列优化DP(超详细!!!)

    一、概念

    1、单调队列定义:   

    其实单调队列就是一种队列内的元素有单调性(单调递增或者单调递减)的队列,答案(也就是最优解)就存在队首,而队尾则是最后进队的元素。因为其单调性所以经常会被用来维护区间最值或者降低DP的维数已达到降维来减少空间及时间的目的。

    单调队列的一般应用:     

    1. 维护区间最值     
    2. 优化DP

    【例一】求m区间内的最小值(洛谷 P1440)

    题目描述

    一个含有n项的数列(n<=2000000),求出每一项前的m个数到它这个区间内的最小值。若前面的数不足m项则从第1个数开始,若前面没有数则输出0。

    输入格式

    第一行两个数n,m。 第二行,n个正整数,为所给定的数列。

    输出格式

    n行,第i行的一个数ai,为所求序列中第i个数前m个数的最小值。

    输入

    6 2

    7 8 1 4 3 2

    输出

    0 7 7 1 1 3


     思路:

    1、暴力枚举以i-1为结尾的前m个数。时间O(n*m),T T T.

    2、rmq求解O(nlog n) 貌似会T

    3、线段树求解 O(nlog n) 当n=1e7时也超时,空间,代码量大 需要更优的O(n)的解法处理。

    4、单调队列来了 因为每一个答案只与当前下标的前m个有关,所以可以用单调队列维护前m个的最小值,   

    考虑如何实现该维护的过程??   

    显然当前下标X的m个以前的元素(即下标小于X-M+1的元素)肯定对答案没有贡献,所以可以将其从单调队列中删除。   

    对于两个元素A,B,下标分别为a,b,如果有A>=B&&a<b那么B留在队列里肯定优于A,因此可以将A删除。    

    维护队首:如果队首已经是当前元素的m个之前,将head++,弹出队首元素   

    维护队尾:比较q[tail]与当前元素的大小,若当前元素更优tail--,弹出队尾元素,直到可以满足队列单调性后加入当前元素。   

    考虑单调队列的时间复杂度:由于每一个元素只会进队和出队一次,所以为O(N)。   

    一般建议用数组模拟单调队列进行操作,而不用系统自带的容器,因为系统自带容器不易调试且可能有爆空间的危险。


     【 例 2】修剪草坪(信息学奥赛一本通 1599)

    【题目描述】

    在一年前赢得了小镇的最佳草坪比赛后,FJ 变得很懒,再也没有修剪过草坪。现在,新一轮的最佳草坪比赛又开始了,FJ 希望能够再次夺冠。 然而,FJ 的草坪非常脏乱,因此,FJ 只能够让他的奶牛来完成这项工作。FJ 有 N 只排成一排的奶牛,编号为 1 到 N。每只奶牛的效率是不同的,奶牛 i的效率为 Ei 。 靠近的奶牛们很熟悉,如果 FJ 安排超过 K 只连续的奶牛,那么这些奶牛就会罢工去开派对。因此,现在 FJ 需要你的帮助,计算 FJ 可以得到的最大效率,并且该方案中没有连续的超过 K 只奶牛。

    【输入】

    第一行:空格隔开的两个整数 N和 K; 第二到 N+1 行:第 i+1 行有一个整数 Ei 。

    【输出】

    一行一个值,表示 FJ 可以得到的最大的效率值。

    【输入样例】

    5 2

    1

    2

    3

    4

    5

    【输出样例】

    12


    sol:

    设 dp[i][0] 表示以 i 结尾并且 i 不选所得的最大效率值

    dp[i][1]表示以 i 结尾并且 i 要选所得的最大效率值

    S[i]表示前缀和

    转移方程为:

    dp[i][0]=max(dp[i-1][0],dp[i-1][1])

    dp[i][1]=max(dp[x][0]+S[i]-S[x]);(i-m≤x<i)

    可以变形为dp[i][1]=max(dp[x][0]-S[x])+S[i];(i-m≤x<i)

    因此dp[i][1]可以用单调队列优化,维护队首为dp[i][0]-S[i]最大的单调队列

  • 相关阅读:
    ES6获取页面所有页面标签名
    改变this对象的指向
    构造函数及原型
    全局对象this转为局部对象
    节点注意的问题
    Spark研究笔记17:设置 CVT
    Spark研究笔记15:资源 CVT
    Spark研究笔记13:Swing 组件类 CVT
    Spark研究笔记16:搜索 CVT
    Spark研究笔记19:插件体系开发 CVT
  • 原文地址:https://www.cnblogs.com/ljy-endl/p/11638389.html
Copyright © 2011-2022 走看看