前置知识
矩阵快速幂
我们以斐波那契问题为一个例子引入。
首先,我们不妨考虑三个数:
F
(
n
)
,
F
(
n
−
1
)
,
F
(
n
−
2
)
F(n),\>\>F(n-1),\>\>F(n-2)
F(n),F(n−1),F(n−2)
注意到递推式
F
(
n
)
=
F
(
n
−
1
)
+
F
(
n
−
2
)
F(n)=F(n-1)+F(n-2)
F(n)=F(n−1)+F(n−2) 其实是一个动态转移方程,考虑DP(废话)
于是我们得到了一个
O
(
n
)
O(n)
O(n) 的DP。
我们可以考虑优化空间,把数组滚动存储,变成
O
(
1
)
O(1)
O(1) 的空间复杂度。
得到如下的伪代码:
b
+
c
→
a
a
→
b
b
→
c
\begin{matrix}b+c\to a\\a\to b\\b\to c\end{matrix}
b+c→aa→bb→c
这不是都会吗我讲它干啥
我们将这玩意压缩成一个矩阵
[
F
(
n
)
F
(
n
−
1
)
]
\begin{bmatrix}F(n)\\F(n-1)\end{bmatrix}
[F(n)F(n−1)]
注意到
[
F
(
n
)
F
(
n
−
1
)
]
=
[
F
(
n
−
1
)
+
F
(
n
−
2
)
F
(
n
−
1
)
]
=
[
1
1
1
0
]
×
[
F
(
n
−
1
)
F
(
n
−
2
)
]
=
[
1
1
1
0
]
n
−
2
×
[
F
(
2
)
F
(
1
)
]
\begin{bmatrix}F(n)\\F(n-1)\end{bmatrix}=\begin{bmatrix}F(n-1)+F(n-2)\\F(n-1)\end{bmatrix}=\begin{bmatrix}1&1\\1&0\end{bmatrix}\times\begin{bmatrix}F(n-1)\\F(n-2)\end{bmatrix}=\begin{bmatrix}1&1\\1&0\end{bmatrix}^{n-2}\times\begin{bmatrix}F(2)\\F(1)\end{bmatrix}
[F(n)F(n−1)]=[F(n−1)+F(n−2)F(n−1)]=[1110]×[F(n−1)F(n−2)]=[1110]n−2×[F(2)F(1)]
所以将幂的那一部分提出来,快速幂一下,没了。
总结一下:
对于当前一组DP状态可以由上一组线性组合得到时,不妨将多个DP状态放进一个矩阵里,然后由前一组DP状态乘上一个转移矩阵得到下一组状态,迭代回初始状态,快速幂一下。
算法性能
- 时间复杂度: O ( m 3 log n ) O(m^3\log n) O(m3logn)
- 空间复杂度: O ( m 2 ) O(m^2) O(m2)
注: m m m 为一组状态的数量, n n n 为迭代的次数