Dp优化总结

按照Dp转移的形式进行分类

一.$Dp[i]=Dp[j]+w(j)$

  1.模型转化:从所有合法的决策j中选出最优决策

  2.单调队列优化:当决策点范围具有单调性时(例如$Dp[i]=Dp[j]+w(j),i-5<=j<i$)可以使用一个双端队列进行优化

    1.代码流程:

      1.for循环每一层时加入新的决策并将队尾决策弹出保证队列内决策单增

      2.将队首不合法的决策弹出

      3.用队首的决策更新Dp[i]

    2.例题:OJ 925 1040 1042 1026

  3.数据结构优化:当决策点并不单调但是连续时(例如$Dp[i]=Dp[j]+w(j),i-a[i]<=j<i$),可以使用线段树或者树状数组优化,需要额外付出$O(logn)$的时间复杂度。

  4.CDQ分治优化:党决策点不连续,但是满足偏序规律时,可以使用CDQ分治优化,需要额外付出$O(logn)$的时间复杂度。

    1.例题:OJ 1442 1445 1512 1556

二.$Dp[j]=f(i)f(j)+Dp[i]$

  1.模型转化:将每一个决策看做平面上一个点$(f(j),Dp[j])$,一条斜率为$f(i)$的直线经过这些点中的一个,$Dp[i]$就是这条直线与y轴的截距

  2.单调队列斜率优化:当$f(i),f(j)$均单调时可以用一个双端队列进行优化

    1.代码流程:

      1.将队首不合法的决策弹出

      2.比较队首决策,若转移到第二个决策更优就弹出队首决策

      3.将新决策加入队列,并保证平面内的点形成下凸包(或者上凸包)

      4.用队首决策更新$Dp[i]$

    2.例题:OJ 1121 1226 1228 1229

  3.单调栈斜率优化:当只有$f(j)$单调时,可以使用单调栈斜率优化,相较于第一种,这种优化方法需要保存所有的决策,每次更新时需要用二分的方法找到最合适的决策点

    1.例题:OJ 1120

  4.CDQ分治优化:若$f(j),f(i)$均不单调,就使用CDQ分治优化吧,通过排序使得$f(j)$单调,再使用单调栈即可

    1.例题:OJ 1443

三.$Dp[i]=f(i,j)$

  1.模型转化:对每一个决策看成一个关于$i$的函数,更新看成用$x=i$这条直线去与之前的每一条函数形成交点,用交点的纵坐标的最优值来更新$Dp[i]$

  2.决策单调性优化:即若$i_1,i_2,i_1<i_2$的最优决策分别为$j_1,j_2$,则$j_1<=j_2$,这种情况的典型特征就是决策函数的导函数也单调,如$Dp[i]=(i-j)^2$,则可以使用决策单调性优化。对于$j_1,j_2,j_1<j_2$,存在一个值$k$,使得$k$之前用$j_1$转移更优且$k$及$k$之后用$j_2$转移更优,$k$就是$j_1,j_2$两条决策函数的交点横坐标,在这里记$k$为$find(j_1,j_2)$。

    1.代码流程:

      1.取出队首两个元素$j_1,j_2$,若$i>=find(j_1,j_2)$,则弹出$j_1$

      2.加入新的决策点,若记加入后队尾三个元素从前到后以此为$j_1,j_2,j_3$,则需保证$find(j_1,j_2)<find(j_2,j_3)$,否则弹出$j_2$

      3.用队首决策点更新$Dp[i]$

    2.例题:OJ 1388 1389 1390 1391 1392 1393

  3.四边形不等式:四边形不等式用于证明决策单调性,若$f(i,l)+f(j,k)>=f(i,k)+f(j,l),i<j<k<l$,则满足决策单调性,证明略

猜你喜欢

转载自www.cnblogs.com/PHDHD/p/12561540.html