按照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$,则满足决策单调性,证明略