wqs二分

直奔主题

直接举例子吧,考虑这样一个问题:给定一个长为 \(n\) 的数列,要选恰好 \(k\) 个不交的子段使得选择的子段总和最大。

朴素 DP

朴素 DP 是设 \(f_{i,j,0/1}\) 表示考虑前 \(i\) 个选择 \(j\) 段最后一个有没有选的最大收益,时间复杂度 \(O(n^2)\) ,必须有一维 \(j\) 处理“恰好”这个限制。

有没有更优秀的复杂度呢?

带权二分

\(F(x) = \max \{ f_{n,x,0}, f_{n,x,1} \}\) ,也就是选择恰好 \(x\) 个不交子段的最大收益。注意到虽然不能直接求出 \(F(k)\) ,但是求出 \(\max\{F(x)|1 \le x \le n\}\) ,也就是函数的最值(以及函数取最值的位置)是不难的(可以直接去掉上述 DP 的第二维)。如果取最值的位置恰为 \(k\) 就能得到答案。

可惜最值并不一定取在 \(x = k\) ,但是可以考虑做一个调整,如果魔改问题,钦定每选一个子段就可以得到 \(p\) 的额外收益,那么此时恰好选 \(x\) 个子段的最大收益就是 \(F(x) + px\) ,如果 \(p\) 选取合适,就能让 \(G(x) = F(x) + px\) 的最值恰好取在 \(x = k\) ,此时 \(F(k) = G(k) - pk\) 就是答案。

如何选择这样一个 \(p\) 呢?把这个问题抽象到二维平面,可以发现 \((x, F(x))\) 构成了一个凸包,而 \(F(x) + px\) 的意义就是斜率为 \(-p\) 的直线在该点上的截距。这样以来不难发现这个 \(p\) 是可二分的,这个二分过程就是 wqs 二分。

懒得画图,不配图了。

扩展

wqs 二分也可以嵌套,比如 CF739E 一题中,有两个不同的数列,要分别选取 \(a, b\) 个元素并最大化收益,其中如果有一个位置在两个数列中同时被选会有一定的代价。

朴素 DP 是设 \(f_{i,j,k}\) 表示考虑前 \(i\) 个位置在两个部分分别选 \(j, k\) 个元素的最大收益,复杂度 \(O(n^3)\)

\(F(j,k) = f_{n,j,k}\) ,抽象到三维空间上就是点 \((j, k, F(j, k))\) 构成的三维凸包!于是可以拿一个平面去截这个三维凸包。也就是确定两个附加代价 \(p, q\) ,使得 \(G(j,k) = F(j,k) - jp - kq\) ,那就可以求出也就是平面 \(z = px + qy + K\) 截出来的截距 \(K\) 。二分套二分即可求解,复杂度 \(O(n log^2 n)\)

三维空间可能有点抽象,也不一定要从这个角度理解,从二分套二分(也就是先来个 wqs 二分,然后对于新的问题继续 wqs 二分)的角度可能更容易理解,也更接近实现。