倍增优化 DP

这个倍增优化 DP 其实是类似于一个矩阵乘法加速递推的形式

因而其普遍取时间复杂度 \(O(n^3\log P)\)

因此有一个特征就是前面 \(n\) 很小但是 \(P\) 很大的话一般就会这样

单次的转移方程非常好写类似于 Floyd 的变体,即

\[f_{i,j}=f_{i,k}\circ f_{k,j} \]

当然 \(\circ\) 能够表示非常多的运算,但是一定要有结合律

因为每一次快速幂都要做一次这样的东西所以时间复杂度就要类似于矩阵乘的 \(O(n^3)\)

所以这种优化一般都是有迹可循的


矩阵加速递推是一个 \(x_i=Ax_{i-1}\) 的形式

其中 \(x_i\) 是向量,\(A\) 是一个转移矩阵,显然它是一个 \(n\) 阶的

这个转移矩阵显然是一个系数矩阵,这个系数矩阵天然等价于转移的方程组

而这个方程组实际上只有一个状态转移方程,就是 \(x_{i,1}\) 也就是 \(f_i\) 的状态转移方程

别的只需要系数从单位矩阵往前移 \(1\) 位就可以

例如斐波那契数列的状态转移方程 \(f_i=f_{i-1}+f_{i-2}\)

就可以写成

\[\begin{cases}x_{i,1}=x_{i-1,1}+x_{i-2,2}\\x_{i,2}=x_{i-1,1}\end{cases} \]

直接把系数抄成矩阵,就是

\[A=\begin{bmatrix}1&1\\1&0\end{bmatrix} \]

一般而言,这个矩阵是一个满秩的矩阵,

不然的话就意味着某些变量实际上是可以去掉的


例题

CF582B

注意到 \(n\leq 100\)\(T=10^7\) 的规模,考虑倍增优化

倍增优化的一个关键点就是考虑中间的合并项,

考虑 \(f_{i,j}\) 表示所有以 \(k_1T+i\) 开头,\(k_2T+j\) 结尾的最长不降子序列

状态转移方程即为 \(f_{i,j}=\max(f_{i,j}+f_{j,k})\)

初始化就是第一个周期内的情况

点击查看代码
一个更直观的理解方式就是直接考虑值域上DP,这样的复杂度是 V^3log T

考虑将值域离散化即可得到 n^3log T,但是实测不需要离散化

ICPC2025Chengdu R B

我们必须知道两个集合才可能确定限制,考虑状压

注意到 \(n\leq 6\Rightarrow 2^n\leq 64,P=10^9\) 的规模,考虑倍增优化

定义 \(f_{i,j}\) 表示打头的第一轮用 \(i\)这一轮结尾的下一轮被钦定\(j\) 的最小值

这里要这么定义主要是为了防止开头结尾都要枚举导致时间复杂度错误,

倍增优化的dp转移只能是 \(O(n^3)\)

时间复杂度 \(O(Tn^3\log P)\) 注意常数

NOIOnline 2020 #1J 魔法

先随便 floyd 一下,考虑枚举第 \(k\) 条边反转,\(n^2\) 更新在所有可能的某条边翻转之后 \((i,j)\) 的路径最短值

然后直接矩阵加速递推就可以了,单次的转移方程显然和 floyd 的状态转移方程一致

时间复杂度 \(O(n^2m+n^3\log k)\)

posted @ 2026-02-10 01:13  2K22  阅读(4)  评论(0)    收藏  举报