1. 程式人生 > >矩陣加速遞推

矩陣加速遞推

關於矩陣加速數列遞推:

給定一個遞推數列 \(f[i] = a_1*f[i-1] + a_2*f[i-2] … a_k*f[i-k]\) ,我們普通計算的話肯定是逐個計算,複雜度較大。

我們可以用矩陣表示:

\[ \left[ \begin{matrix} f[i] \\ f[i-1] \\ … \\ f[i-k] \end{matrix} \right] \]

為了遞推出 \(f[n]\) ,我們需要找到一個係數矩陣 \(A\) 使得:

\[ \left[ \begin{matrix} f[i] \\ f[i-1] \\ … \\ f[i-k] \end{matrix} \right] = A\times \left[ \begin{matrix} f[i-1] \\ f[i-2] \\ … \\ f[i-k-1] \end{matrix} \right] \]

就可以這樣計算:

\[ \left[ \begin{matrix} f[n+k] \\ f[n+k-1] \\ … \\ f[n] \end{matrix} \right] = A^{n-1}\times \left[ \begin{matrix} f[k] \\ f[k-1] \\ … \\ f[1] \end{matrix} \right] \]

通過矩陣快速冪來計算 \(A^n\) 可以減小複雜度,問題是如何找到一個 \(A\) 矩陣

容易發現,\(A\)矩陣可以這樣構造:

\[ \left[ \begin{matrix} a_1 & a_2 & … & a_k-1 & a_k \\ 1 & 0 & … & 0 & 0 \\ 0 & 1 & … & 0 & 0 \\ … & … & … & … & … \\ 0 & 0 & … & 1 & 0 \end{matrix} \right] \]

即第一行為係數,從 \(A_{2,1}\) 開始的一條斜線為 \(1\), 其餘為 \(0\),這樣構造可以保證 \(f[i]\) 被計算出來了,而其餘的元素都繼承了上一個矩陣的值。

至此,我們可以愉快地用矩陣加速遞推數列了。