线性递推求值问题

常系数线性递推关系的定义

对于满足
a n = ∑ i = 1 k c i a n − i + f ( n ) a_n=\sum_{i=1}^{k}c_ia_{n-i}+f(n) an=i=1kciani+f(n)
一类的递推关系(其中 c , k c,k c,k 为常数),我们称之为常系数线性递推关系。

只要给定 a 0 , a 1 , … , a k − 1 a_0,a_1,\dots,a_{k-1} a0,a1,,ak1 以及 c 1 , c 2 , … , c k c_1,c_2,\dots,c_k c1,c2,,ck 以及 f ( n ) f(n) f(n) ,我们就能求出 a a a 的任意一项。

这个问题的一般形式是不能快速求解的,比如令 f ( n ) = ln ⁡ n f(n)=\ln n f(n)=lnn 。但有一些特殊形式我们可以快速求解。我们先从齐次常系数线性递推关系来研究。

齐次常系数线性递推关系的求值

齐次常系数线性递推关系即 f ( n ) = 0 f(n)=0 f(n)=0 的情况,此时 a n = ∑ i = 1 k c i a n − i a_n=\sum_{i=1}^{k}c_ia_{n-i} an=i=1kciani

这看起来像线性变换,因此考虑从线性变换的角度解决这个问题。

矩阵优化

我们构造初始向量

x ⃗ = [ a k − 1 a k − 2 ⋮ a 1 a 0 ] \vec x= \left[ \begin{matrix} a_{k-1} \\ a_{k-2} \\ \vdots \\ a_1 \\ a_0 \\ \end{matrix} \right] x =ak1ak2a1a0

以及转移矩阵

A = [ c 1 c 2 ⋯ c k − 2 c k − 1 c k 1 0 ⋯ 0 0 0 0 1 ⋯ 0 0 0 ⋮ ⋮ ⋱ ⋮ ⋮ ⋮ 0 0 ⋯ 1 0 0 0 0 ⋯ 0 1 0 ] A= \left[ \begin{matrix} c_1 &c_2 &\cdots &c_{k-2} &c_{k-1} & c_k\\ 1 & 0 &\cdots & 0 & 0 & 0 \\ 0 & 1 &\cdots & 0 & 0 & 0 \\ \vdots &\vdots & \ddots &\vdots &\vdots &\vdots \\ 0 & 0 &\cdots & 1 & 0 & 0 \\ 0 & 0 &\cdots & 0 & 1 & 0 \\ \end{matrix} \right] A=c11000c20100ck20010ck10001ck0000

于是

A n ⋅ x ⃗ = [ a n + k − 1 a n + k − 2 ⋮ a n + 1 a n ] A^n\cdot \vec x= \left[ \begin{matrix} a_{n+k-1}\\ a_{n+k-2} \\ \vdots \\ a_{n+1}\\ a_n\\ \end{matrix} \right] Anx =an+k1an+k2an+1an

这样我们就可以用矩阵快速幂来求 a n a_n an 了,复杂度 O ( k 3 log ⁡ n ) O(k^3\log n) O(k3logn)

但这个复杂度依然不够优秀,考虑从线性代数的角度切入。

特征多项式优化

事实上,我们可以把 A n A^n An 表示为 A 0 , A 1 , ⋯   , A k − 1 A^0,A^1,\cdots,A^{k-1} A0,A1,,Ak1 的线性组合,并且我们有:

A n = ∑ i = 1 k c i A n − i A^{n}=\sum_{i=1}^{k} c_iA^{n-i} An=i=1kciAni

为什么呢?
我们可以从 C a y l a y − C a m i l t o n Caylay-Camilton CaylayCamilton 定理1来考虑:

对于矩阵 A A A 的特征多项式 f ( λ ) = det ⁡ ∣ λ I − A ∣ f( \lambda )=\det \left| \lambda I-A\right| f(λ)=detλIA ,我们有 f ( A ) = 0 f(A)=0 f(A)=0

而对于上述转移矩阵,我们有:

f ( λ ) = λ k − ∑ i = 1 k c i λ n − i f(\lambda)=\lambda ^k-\sum_{i=1}^{k}c_i \lambda ^{n-i} f(λ)=λki=1kciλni

A A A 代入上式即可。

当然我们也可以从其他角度考虑。

A n ⋅ x ⃗ = [ a n + k − 1 a n + k − 2 ⋮ a n + 1 a n ] A^{n}\cdot \vec x= \begin{bmatrix} a_{n+k-1}\\ a_{n+k-2} \\ \vdots \\ a_{n+1}\\ a_n\\ \end{bmatrix} Anx =an+k1an+k2an+1an

∑ i = 1 k c i A n − i ⋅ x ⃗ = [ ∑ i = 1 k c i a n − i + k − 1 ∑ i = 1 k c i a n − i + k − 2 ⋮ ∑ i = 1 k c i a n − i + 1 ∑ i = 1 k c i a n − i ] = [ a n + k − 1 a n + k − 2 ⋮ a n + 1 a n ] = A n ⋅ x ⃗ \sum_{i=1}^{k} c_iA^{n-i}\cdot \vec x= \begin{bmatrix} \sum_{i=1}^kc_ia_{n-i+k-1}\\\\ \sum_{i=1}^kc_ia_{n-i+k-2}\\\\ \vdots \\\\ \sum_{i=1}^kc_ia_{n-i+1}\\\\ \sum_{i=1}^kc_ia_{n-i}\\\\ \end{bmatrix}= \begin{bmatrix} a_{n+k-1}\\\\ a_{n+k-2} \\\\ \vdots \\\\ a_{n+1}\\\\ a_n\\\\ \end{bmatrix}= A^{n}\cdot \vec x i=1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值