单调队列优化DP
通法:
写的时候要灵活变通(可以考虑类似于双指针的技巧,如跳房子)。
套个二分,然后由于与位置相关,所以维护一个左端点和右端点,右端点考虑最短步长会不会跳过头,左端点考虑最长步长会不会跳不到。
满足连续性质,所以一次考虑一段,\(f_i\) 保证 \(i\) 不工作,转移时保证连续段不超过即可。
考虑到每次转移可以按照行或列来划分,这样每次就是序列上的滑动窗口了,注意遇到障碍物清空队列。
本质是一个贪心,但是贪心用到了类似单调栈的思想(便宜的油),而且用油时继续贪心,先用小的,一个从尾部弹出,一个从头部弹出,而插入新的油是从尾部,单调队列的形式,但是头部弹出并不是越界,而是使用。
这道题首先要把出发时间的限制搞掉,这样就可以看作一批批出发了;接着分批返回一定不劣,这样就可以枚举最后一批来转移了,然后就有两种情况,一个是间隔影响,一个是最晚出发时间影响,然后随便算一下,分类讨论拆掉max,在根据单调增的性质直接在队首移动,队首附近就是两种情况的最值,最后注意边界情况的讨论。
首先需要倒序处理,这样更容易。发现单调性,从而发现只要满足条件,下标大的更优;然后根据又小又强保证单调增(因为满足条件只需要 \(s_k+g_k\),所以只有一种选择,直接根据这个维护单调序列)。
总结
-
大多数的题左右端点的移动很有讲究,各有特色:如果遇到跳房子这样下标不是一般的,那么用双指针更方便,因为每次插入和删除不一定是一个。
-
这类问题有很多不是考虑最后一个,而是最后一段捆绑成一组考虑转移。
-
单调队列有些只是形式,并非真正的单调队列,如汽油补给。
-
常常与某些贪心结合,如列车、干草堆。
-
单调性比较容易发现,一般只需要移项 \(1\sim 2\) 次即可。
-
两大重要类型:见 https://www.cnblogs.com/wscqwq/p/17731030.html#线性中的重要两大类
容易发现这几道例题都属于这两大类