斜率优化DP
终于学会了斜率优化DP,每次学一个新东西我都感觉要费老大劲。还是太菜了
学懂之后感觉其实并不是很难,当然能发明出这个算法的人不得不说真是太厉害了,能开创性地想到用函数维护
而斜率优化的核心就已经说完了,具体讲就是:
将
那么函数的
而决策点
(图是转luogu日报的,暂时未要到版权,若不允许转载请联系博主,侵删。)
满足这张图的题目,显然要求截距的最小,那么这个第一次遇到的点可以达到最小截距。
-
可以不断出队
head 来让队首最优,每次O(1) 得到最优决策点。 -
也可以在整个队列中二分查找,每次
O(logn) 查询最优决策点。
第一个显然复杂度更优是
简述单调队列:
-
每个
DP[i] 的斜率为正时,维护一个下凸壳,斜率依次要求单调不减,故:-
在每次加入新的点时,由于其横坐标更大,故此点一定要进去下凸壳中,而为了保证下凸壳依然下凸,需要保证当前点
i 与队尾tail 的斜率大于i 与(tail-1) 的斜率,即为:K(i,tail)> K(i,tail-1) ,则(while) (K(i,tail)<= K(i,tail-1)) 时,tail-- 将队尾出队,以此来维护下凸壳。 -
当队列
head 和head+1 的斜率小于等于当前i 的斜率时,head 这个点一定不是当前i 对应直线向上平移时的第一个交点了,而且之后的直线斜率增大,故这个head 再也不可能对答案有贡献,将其while(K(head,head+1)<=slope(i)) \ \ head++ ,以此来维护单调队列保证head 就是最优决策点。
-
-
每个
DP[i] 的斜率为负时,维护一个上凸壳,斜率要求单调不增,具体情况和上面类似,只是大于号小于号相反。
简述二分查找:
(待填.....)
例题1:P3195 [HNOI2008]玩具装箱TOY
(同上...)
例题2:P3628 [APIO2010]特别行动队
(同上)
例题3:P3648 [APIO2014]序列分割
(同上.....)