已知数列 { a 0 , a 1 , ⋯   , a n − 1 } \{a_0,a_1,\cdots,a_{n-1}\} {a0,a1,⋯,an−1},求其最短线性递推式。即求数列 { r 0 , r 1 , ⋯   , r m − 1 } \{r_0,r_1,\cdots,r_{m-1}\} {r0,r1,⋯,rm−1}满足 ∀ i ∈ [ m , n ) , a i = ∑ j = 1 m r j − 1 a i − j \forall i\in[m,n),a_i=\sum_{j=1}^mr_{j-1}a_{i-j} ∀i∈[m,n),ai=∑j=1mrj−1ai−j。
考虑不停地修改答案递推式。设 R p R_p Rp表示得到的第 p p p个递推式,最开始的递推式为空,即 R 0 = { } R_0=\{\} R0={}。记 d i d_i di为由当前递推式算出的 a i a_i ai与 a i a_i ai的差。如果 d i = 0 d_i=0 di=0那么说明递推式到 i i i都是对的,否则记 f p f_p fp表示 R p R_p Rp的错误位置。考虑如何修改当前的 R R R。设新的递推式为 R p + 1 R_{p+1} Rp+1,事实上,我们把 R p R_p Rp加上 R ′ R' R′即可,其中 R ′ R' R′是 i − f p − 1 − 1 i-f_{p-1}-1 i−fp−1−1个 0 0 0拼上 M M M拼上 R p − 1 R_{p-1} Rp−1的 − M -M −M倍,其中 M = d i d f p − 1 M=\frac{d_i}{d_{f_{p-1}}} M=dfp−1di。每次最多修改 n n n项,最多修改 n n n次,复杂度为 O ( n 2 ) O(n^2) O(n2)。
举例说明:
先填上开头。
a | 1 | 2 | 4 | 7 | 14 | 24 | |
---|---|---|---|---|---|---|---|
d | N/A | -1 | |||||
R | {} | {0} |
计算 d 1 = 0 × a 0 − a 1 = − 2 d_1=0\times a_0-a_1=-2 d1=0×a0−a1=−2,不符合。计算 R ′ R' R′是 0 0 0个 0 0 0(现在的位置-上次不符合位置+1)拼上 M M M拼上 { } \{\} {}的 − M -M −M倍, M = − 2 − 1 M=\frac{-2}{-1} M=−1−2,算得 { 2 } \{2\} {2}。于是 R = { 0 } + R ′ = { 2 } R=\{0\}+R'=\{2\} R={0}+R′={2}。
a | 1 | 2 | 4 | 7 | 14 | 24 | |
---|---|---|---|---|---|---|---|
d | N/A | -1 | -2 | ||||
R | {} | {0} | {2} |
计算 d 2 = 2 × 2 − 4 = 0 d_2=2\times 2-4=0 d2=2×2−4=0符合。
a | 1 | 2 | 4 | 7 | 14 | 24 | |
---|---|---|---|---|---|---|---|
d | N/A | -1 | -2 | 0 | |||
R | {} | {0} | {2} |
计算 d 3 = 1 d_3=1 d3=1不符合, R ′ R' R′是 1 1 1个 0 0 0拼上 M M M拼上 { 0 } \{0\} {0}的 − M -M −M倍, M = 1 − 2 M=\frac{1}{-2} M=−21。
a | 1 | 2 | 4 | 7 | 14 | 24 | |
---|---|---|---|---|---|---|---|
d | N/A | -1 | -2 | 0 | 1 | ||
R | {} | {0} | {2} | {2,-0.5,0} |
注意这里的 R R R只对 7 7 7适用,因为它的长度有 3 3 3。
之后的请自行计算,不再展示过程。
a | 1 | 2 | 4 | 7 | 14 | 24 | |
---|---|---|---|---|---|---|---|
d | N/A | -1 | -2 | 0 | 1 | -2 | 0.5 |
R | {} | {0} | {2} | {2,-0.5,0} | {0,3.5,0} | {-0.25,4,-0.125,0} |
4.26