算法笔记--单调队列优化dp

单调队列:队列中元素单调递增或递减,可以用双端队列实现(deque),队列的前面和后面都可以入队出队。

单调队列优化dp:

问题引入:

dp[i] = min( a[j] ) ,i-m < j <= i

普通的做法是O(nlogn),但是当n很大是,这个复杂度就不行了,考虑用单调队列优化来达到O(n)。

单调队列优化dp时维护的一般都是两个值{ id(下表),value(值)},且它们都保持单调。

对于这个问题,我们维护一个两个值都单调递增的序列。

查询:队首不断删除,直到队首下标大于等于i - m + 1,队首就是答案。

插入:因为要保证下标单调递增,所以从队尾加入元素a[i],因为又要保证值单调递增,所以我们不断删除队尾大于a[i]的元素,直到队尾小于a[i]或者队列为空,然后在队尾添加a[i]。

为什么我们能直接删除队尾大于a[i]的元素呢?

因为队尾删除的那些元素下标比a[i]小且值比a[i]大,如果这些元素可以是答案,那么a[i]肯定比他们好,所以这些值不会对答案产生贡献,所以直接删除就好了。

最后,每个元素最多入队一次,出队一次,复杂度为O(n)。

猜你喜欢

转载自www.cnblogs.com/widsom/p/9298088.html