CF1768F

dp+根号分治,配得上省选题的难度。

一眼 dp,虽然暴力肯定过不了,但是把朴素转移先列出来绝对没坏处。

dpi=min1j<i(dpj+minjkiak×v)dp_i=\min\limits_{1\leq j<i}(dp_j+\min\limits_{j\leq k\leq i}a_k\times v)

这个东西很难用 DS 维护,有 min\min 的存在又很难斜优啥的,就想到有一种方法优化:限制可行状态数。

假设要求从 ii 跳到 jj。若一步从 iijj 是最优的,那么它的花费一定小于一步一步跳的花费,即

minikjak×(ij)2(ij)×n\min\limits_{i\leq k\leq j}a_k\times(i-j)^2\leq(i-j)\times n

这是因为值域上界为 nn

化简一下,得到

minikjaknij\min\limits_{i\leq k\leq j}a_k\leq \frac n{i-j}

看到分数就可以想到根号分治。

  • ijni-j\leq\sqrt n 时,暴力枚举 jj 转移。时间复杂度 O(n)O(\sqrt n)

  • ij>ni-j>\sqrt n 时,枚举 minikjak\min\limits_{i\leq k\leq j}a_k。又因为有一个性质:最优情况下一定有 k=ik=ik=jk=j。因为 ((ik)2+(kj)2)×ak(ij)2×ak((i-k)^2+(k-j)^2)\times a_k\leq(i-j)^2\times a_k。这时又可以分两种情况。

  • k=jk=j 时,记录每一个 n\leq \sqrt n 的数上一次出现的位置,每次枚举转移。时间复杂度 O(n)O(\sqrt n)

  • k=ik=i 时,如果 aina_i\leq \sqrt n,从 ii 往前暴力枚举转移,直到遇到一个 akaia_k\leq a_i 为止。这一部分的复杂度呢?根据楼上大佬的说法,“对于 [1,n][1,\sqrt n] 内的每个值,最多可能扫完整个序列一次”。所以均摊复杂度 O(n)O(\sqrt n)

总时间复杂度 O(nn)O(n\sqrt n)。其他的不说,这个分讨的复杂度太优美了。

Submission