C++ 中求第 N 項(矩陣冪運算示例)


在這個問題中,我們給定一個整數 N 和一個遞迴函式,該函式給出了第 N 項作為其他項的函式。我們的任務是建立一個程式來查詢第 N 項(矩陣冪運算示例)。

函式為:

T(n) = 2*( T(n-1) ) + 3*( T(n-2) )
Initial values are
   T(0) = 1 , T(1) = 1

讓我們來看一個例子來理解這個問題:

輸入

N = 4

輸出

41

解釋

T(4) = 2* (T(3)) + 3*(T(2))
T(4) = 2* ( 2*(T(2)) + 3*(T(1)) ) + 3*( 2* (T(1)) + 3*(T(0)) )
T(4) = 2*( 2*(2* (T(1)) + 3*(T(0))) + 3*(1) ) + 3*(2*(1) + 3*(1))
T(4) = 2*(2 * (2 *(1) + 3*(1) )) + 3 ) + 3 * (5)
T(4) = 2*(2 * (2 + 3) + 3) + 15
T(4) = 2*(2 * (5) + 3) + 15
T(4) = 2*(10 + 3) + 15
T(4) = 2*(13) + 15 = 26 + 15 = 41

解決方案方法

解決這個問題的一個簡單方法是使用遞迴或迭代。我們可以將第 n 項作為對前幾項的遞迴呼叫,並使用初始值來找到結果。

程式說明了我們解決方案的工作原理:

示例

 線上演示

#include <iostream>
using namespace std;
long calcNthTerm(long n) {
   if(n == 0 || n == 1)
      return 1;
   return ( ( 2*(calcNthTerm(n-1)) ) + ( 3*(calcNthTerm(n-2)) ) );
}
int main() {
   long n = 5;
   cout<<n<<"th term of found using matrix exponentiation is "<<calcNthTerm(n);
   return 0;
}

輸出

5th term of found using matrix exponentiation is 121

高效方法

解決這個問題的一個高效方法是使用矩陣冪運算的概念。在這種方法中,我們將使用一個變換矩陣來查詢第 N 項。

為此,我們需要找到變換矩陣。該矩陣取決於相關項的數量(此處為 2),以及初始值 T(0) = 1, T(1)= 1。

變換矩陣的大小為 k*k。當它與大小為 k*1 的初始矩陣相乘時,會返回下一項。

以下是值:

初始矩陣 =

$$\begin{bmatrix}1 & 0 \end{bmatrix}$$

變換矩陣 =

$$\begin{bmatrix}2&3 \\ 1&0 \end{bmatrix}$$

Tn 的值給出為 TM(n-1)*IM

$$\begin{bmatrix}2&3 \\ 1&0 \end{bmatrix}^{n-1}*\begin{bmatrix}1 \\ 1 \end{bmatrix}$$

程式說明了我們解決方案的工作原理:

示例

 線上演示

#include <iostream>
using namespace std;
#define MOD 1000000009
long calcNthTerm(long n) {
   if (n <= 1)
      return 1;
   n--;
   long resultantMat[2][2] = { 1, 0, 0, 1 };
   long transMat[2][2] = { 2, 3, 1, 0 };
   while (n) {
      long tempMat[2][2];
      if (n & 1) {
         tempMat[0][0] = (resultantMat[0][0] * transMat[0][0] +
         resultantMat[0][1] * transMat[1][0]) % MOD;
         tempMat[0][1] = (resultantMat[0][0] * transMat[0][1] +
         resultantMat[0][1] * transMat[1][1]) % MOD;
         tempMat[1][0] = (resultantMat[1][0] * transMat[0][0] +
         resultantMat[1][1] * transMat[1][0]) % MOD;
         tempMat[1][1] = (resultantMat[1][0] * transMat[0][1] +
         resultantMat[1][1] * transMat[1][1]) % MOD;
         resultantMat[0][0] = tempMat[0][0];
         resultantMat[0][1] = tempMat[0][1];
         resultantMat[1][0] = tempMat[1][0];
         resultantMat[1][1] = tempMat[1][1];
      }
      n = n / 2;
      tempMat[0][0] = (transMat[0][0] * transMat[0][0] +
      transMat[0][1] * transMat[1][0]) % MOD;
      tempMat[0][1] = (transMat[0][0] * transMat[0][1] +
      transMat[0][1] * transMat[1][1]) % MOD;
      tempMat[1][0] = (transMat[1][0] * transMat[0][0] +
      transMat[1][1] * transMat[1][0]) % MOD;
      tempMat[1][1] = (transMat[1][0] * transMat[0][1] +
      transMat[1][1] * transMat[1][1]) % MOD;
      transMat[0][0] = tempMat[0][0];
      transMat[0][1] = tempMat[0][1];
      transMat[1][0] = tempMat[1][0];
      transMat[1][1] = tempMat[1][1];
   }
   return (resultantMat[0][0] * 1 + resultantMat[0][1] * 1) % MOD;
}
int main() {
   long n = 5;
   cout<<n<<"th term of found using matrix exponentiation is "<<calcNthTerm(n);
   return 0;
}

輸出

5th term of found using matrix exponentiation is 121

更新於:2021年3月13日

瀏覽量 155 次

啟動您的 職業生涯

完成課程後獲得認證

開始學習
廣告
© . All rights reserved.