集训Day3-DP优化
单调队列优化DP
单调队列
滑窗最值。队列内维护可能成为答案的值。令队首为当前最优解,其次是次优解,...
每次移动,先将队尾更劣解弹出,再将队首离开边界弹出,最后在队尾插入当前值。这样就可以维护。时间复杂度均摊 \(\Theta(n)\),因为每个元素只会最多出入队各一次。
因为队列内根据优劣顺序单调递减,所以叫单调队列。
一般地,我们为方便边界条件,要记录下标。优劣顺序不一定是比大小,所以可以写比较函数。
洛谷P3572
简要题意: 有 \(n\) 棵树,高度分别为 \(a_1,a_2,...,a_n\)。小鸟从树 \(1\) 出发,每次可以从树 \(i\) 移动到树 \({i+1},{i+1},...,{i+k}\)。如果目标树的高度大于等于当前树的,那么会增加 \(1\) 点劳累度。求到树 \(n\) 时最小劳累度。
CF372C
简要题意: 有 \(n\) 个编号连续区域,相邻区域距离为 \(1\)。有 \(m\) 个烟花活动在 \(T_i\) 时间、\(a_i\) 位置举办,对于位于 \(x\) 区域的人会获得 \(b_i-|a_i-x|\) 幸福值(可能为负)。每个单位时间可以走 \(d\)。求最大幸福值。\(n\le 1.5\times 10^5,m\le 300\)
令 \(f_{i,j}\) 表示第 \(i\) 次放烟花时站在 \(j\) 处的累计最大幸福值。则有转移
因为这个 \(\max\) 区间是滑动窗口,所以可以单调队列优化。
时间复杂度 \(\Theta(nm)\),滚动数组优化后空间 \(\Theta(n)\)。
洛谷P2569
简要题意: 在 \(T\) 天内,某只股票在第 \(i\) 天可以以 \(AP_i\) 价买入,以 \(BP_i\) 价卖出,每次买入最多 \(AS_i\) 股,每次卖出最多 \(BS_i\) 股。任意时刻持有数量不超过 \(maxP\),每次买卖行动需间隔 \(W\) 天。\(T,W\le 2000\)
令 \(f_{i,j}\) 为第 \(i\) 天持有 \(j\) 支股票,当前的直接收益。
为方便处理差价,我们令买入时直接减去买价,卖出时直接加上卖价。分不动、买入、卖出三类讨论,就有一个又臭又长的式子:
之所以只取 \(i-W-1\) 天时的取值,是因为我们可以保证它包含了 \(1\sim i-W-1\) 的所有取值。
第二种情况和第三种情况都是滑窗取 \(\max\),用单调队列优化。总时间复杂度为 \(\Theta(T\cdot maxP)\)
多重背包问题
例题:洛谷P1776
给定 \(n\) 种物体,第 \(i\) 种物体有数量 \(m_i\)、价值 \(v_i\)、重量 \(w_i\)。求总重量在 \(W\) 以内最大总价值。\(\sum m_i\le 10^5,n\le 100,W\le 4\times 10^5\)
朴素想法
将每一个物品单独拆开,转为01背包问题。时间复杂度为 \(\Theta(\sum m_i\cdot W)\),不可取。
二进制分组
对于一种物品,我们将其拆成 \(1,2,4,8,16,...,2^k\) 倍的不同单个物品。它就像二进制,可以表示出一个区间:\([0,2^{k+1}-1]\)。
假如物品本来一共 \(m_i\) 个,它大于 \(2^{k+1}-1\),也就是还不能表示 \([2^{k+1},m_i]\)。此时我们可以额外加上一个 \(m_i-2^{k+1}+1\) 大小的物品。这样我们就可以用它加上 \([2\cdot 2^{k+1} - m - 1,2^{k+1}-1]\) 的数表示出所有大小,这些数我们已经表示过了。
这样我们就拆出了 \(\log_2 m_i\) 个物品,再01背包。时间复杂度 \(\Theta(\sum \log_2 m_i\cdot W)\)(也就是 \(\Theta(nW\log m_i)\)),可以通过。
单调队列优化
类似01背包/完全背包,我们同样可以列出转移式:
发现它访问的 \(j-k\cdot w_i\) 对于模 \(w_i\) 意义在同位置,考虑将同余位置放在一块看,发现这是一个滑窗,可以单调队列优化。(很不可做的样子?)
这是一个 \(\Theta(nW)\) 的做法。
当然这个式子也有别的方式转成单调队列的形式。
线段树优化DP
LIS
这里讨论DP做法
这是一个经典 2-side 问题。对于这类二维偏序关系问题,我们的方法很典:扫描线+数据结构。更高维我们需要cdq分治或bitset维护了。

浙公网安备 33010602011771号