以矩阵方式加速递推。
前置知识
矩阵乘法
[
A
1
,
1
A
1
,
2
.
.
.
A
1
,
k
A
2
,
1
A
2
,
2
.
.
.
A
2
,
k
.
.
.
.
.
.
.
.
.
.
.
.
A
n
,
1
A
n
,
2
.
.
.
A
n
,
k
]
×
[
B
1
,
1
B
1
,
2
.
.
.
B
1
,
n
B
2
,
1
B
2
,
2
.
.
.
B
2
,
n
.
.
.
.
.
.
.
.
.
.
.
.
B
k
,
1
B
k
,
2
.
.
.
B
k
,
n
]
=
C
C
i
j
=
∑
x
=
1
k
A
i
x
×
B
x
i
\begin{bmatrix} A_{1,1}&A_{1,2}&...&A_{1,k}\\ A_{2,1}&A_{2,2}&...&A_{2,k}\\ ...&...&...&...\\ A_{n,1}&A_{n,2}&...&A_{n,k}\\ \end{bmatrix} \times \begin{bmatrix} B_{1,1}&B_{1,2}&...&B_{1,n}\\ B_{2,1}&B_{2,2}&...&B_{2,n}\\ ...&...&...&...\\ B_{k,1}&B_{k,2}&...&B_{k,n}\\ \end{bmatrix}=C\\ ~\\ C_{ij} = \sum_{x=1}^{k} A_{ix}\times B_{xi}
A1,1A2,1...An,1A1,2A2,2...An,2............A1,kA2,k...An,k
×
B1,1B2,1...Bk,1B1,2B2,2...Bk,2............B1,nB2,n...Bk,n
=C Cij=x=1∑kAix×Bxi
比如说:
[
A
1
,
1
A
1
,
2
A
1
,
3
A
2
,
1
A
2
,
2
A
2
,
3
]
×
[
B
1
,
1
B
1
,
2
B
1
,
3
B
1
,
4
B
2
,
1
B
2
,
2
B
2
,
3
B
2
,
4
B
3
,
1
B
3
,
2
B
3
,
3
B
3
,
4
]
=
[
C
1
,
1
C
1
,
2
C
1
,
3
C
1
,
4
C
2
,
1
C
2
,
2
C
2
,
3
C
2
,
4
]
\begin{bmatrix} A_{1,1}&A_{1,2}&A_{1,3}\\ A_{2,1}&A_{2,2}&A_{2,3}\\ \end{bmatrix} \times \begin{bmatrix} B_{1,1}&B_{1,2}&B_{1,3}&B_{1,4}\\ B_{2,1}&B_{2,2}&B_{2,3}&B_{2,4}\\ B_{3,1}&B_{3,2}&B_{3,3}&B_{3,4}\\ \end{bmatrix}= \begin{bmatrix} C_{1,1}&C_{1,2}&C_{1,3}&C_{1,4}\\ C_{2,1}&C_{2,2}&C_{2,3}&C_{2,4}\\ \end{bmatrix}\\
[A1,1A2,1A1,2A2,2A1,3A2,3]×
B1,1B2,1B3,1B1,2B2,2B3,2B1,3B2,3B3,3B1,4B2,4B3,4
=[C1,1C2,1C1,2C2,2C1,3C2,3C1,4C2,4]
时间复杂度 O ( n m k ) O(nmk) O(nmk)
矩阵快速幂
用快速幂方式来进行矩阵乘法 O ( n m k log x ) O(nmk\log x) O(nmklogx)
算法用途
用途,还用说吗?字面意思,加速递推。
算法复杂度
矩阵是 n × k n \times k n×k 和 k × m k \times m k×m 的。要递推 x x x 次。
所以快速幂方式来进行矩阵乘法时间复杂度为 O ( n m k log x ) O(nmk\log x) O(nmklogx)
算法实现
此处尝试优化斐波那契数列的 DP 算法。
斐波那契数列 DP 转移方程为:
f i = { 1 ( i ≤ 2 ) f i − 1 + f i − 2 ( i ≤ 3 ) f_i=\begin{cases} 1&(i\leq2)\\ f_{i-1}+f_{i-2}&(i \leq 3)\\ \end{cases} fi={1fi−1+fi−2(i≤2)(i≤3)
我们使用一个矩阵来表示状态。
[ f i f i − 1 ] \begin{bmatrix} f_i\\ f_{i-1}\\ \end{bmatrix} [fifi−1]
然后我们需要求出一个矩阵 A A A 使得 A A A 满足
A × [ f i − 1 f i − 2 ] = [ f i f i − 1 ] A \times \begin{bmatrix} f_{i-1}\\ f_{i-2}\\ \end{bmatrix}= \begin{bmatrix} f_i\\ f_{i-1}\\ \end{bmatrix} A×[fi−1fi−2]=[fifi−1]
可以通过 C i , j = ∑ x = 1 k A x , i × B j , x C_{i,j} = \sum_{x=1}^{k} A_{x,i}\times B_{j,x} Ci,j=∑x=1kAx,i×Bj,x 逆推,容易求得
A = [ 1 1 1 0 ] A=\begin{bmatrix} 1&1\\ 1&0\\ \end{bmatrix} A=[1110]
我们还需要一个初始矩阵 B B B 表示初始状态
斐波那契数列 DP 时
A = [ 1 1 ] A=\begin{bmatrix} 1\\ 1\\ \end{bmatrix} A=[11]
最终答案矩阵为
B × A x B \times A ^ x B×Ax
即
[
1
1
]
×
[
1
1
1
0
]
x
\begin{bmatrix} 1\\ 1\\ \end{bmatrix} \times \begin{bmatrix} 1&1\\ 1&0\\ \end{bmatrix}^x
[11]×[1110]x