행렬을 이용한 피보나치 수열 문제의 해법

1. 피보나치 수열의 행렬 표현

 

피보나치 수열의 점화식은 다음과 같다.

 

$a_{n+1} = a_{n} + a_{n-1}$

 

$a_{n} = a_{n} + 0$

 

따라서 행렬로 나타내면 다음과 같다

 

$$\begin{pmatrix}
a_{n+1} \\
a_{n}
\end{pmatrix}=\begin{pmatrix}
1 & 1 \\
1 & 0 \\
\end{pmatrix}\begin{pmatrix}
a_{n} \\
a_{n-1}
\end{pmatrix}$$

 

n = 1부터 반복적으로 곱해보면...

 

$$\begin{pmatrix}
a_{2} \\
a_{1}
\end{pmatrix}=\begin{pmatrix}
1 & 1 \\
1 & 0 \\
\end{pmatrix}\begin{pmatrix}
a_{1} \\
a_{0}
\end{pmatrix}$$

 

n = 2이면...

 

$$\begin{pmatrix}
a_{n+1} \\
a_{n}
\end{pmatrix}=\begin{pmatrix}
1 & 1 \\
1 & 0 \\
\end{pmatrix}\begin{pmatrix}
1 & 1 \\
1 & 0 \\
\end{pmatrix}\begin{pmatrix}
a_{1} \\
a_{0}
\end{pmatrix}$$

 

정리하면 다음과 같다.

 

$$\begin{pmatrix}
a_{2} \\
a_{1}
\end{pmatrix}=\begin{pmatrix}
1 & 1 \\
1 & 0 \\
\end{pmatrix}^{2}\begin{pmatrix}
a_{1} \\
a_{0}
\end{pmatrix}$$

 

따라서 일반적인 n에 대하여 다음과 같을 것이다.

 

$$\begin{pmatrix}
a_{n+1} \\
a_{n}
\end{pmatrix}=\begin{pmatrix}
1 & 1 \\
1 & 0 \\
\end{pmatrix}^{n}\begin{pmatrix}
a_{1} \\
a_{0}
\end{pmatrix}$$

 

$a_{1}$과 $a_{0}$은 기본적으로 주어지므로,

 

우리는 행렬

 

$$\begin{pmatrix}
1 & 1 \\
1 & 0 \\
\end{pmatrix}^{n}$$

 

 

을 구하면 된다.

 

그리고 나서 n번째 피보나치 항은 $a_{n}$이고 이것을 구해야한다.

 

n제곱한 행렬과

 

$$\begin{pmatrix}
a_{1} \\
a_{0}
\end{pmatrix}$$

 

을 곱해야하는데 $a_{1} = 1$, $a_{0} = 0$이므로

 

결국 n제곱한 행렬의 (1,0) 원소가 구하고자 하는 n번째 피보나치 항이다.

 

행렬의 거듭제곱을 구하는 방법은 이미 배웠다

 

ABC 293 복기 E - Geometric Progression - 행렬곱 배우기 - (tistory.com)

 

ABC 293 복기 E - Geometric Progression - 행렬곱 배우기 -

1. 문제 E - Geometric Progression (atcoder.jp) E - Geometric Progression AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online. atcoder.jp 정수 A,X,M이 주어질 때, $$\sum_{k=0}^{X-1}

deepdata.tistory.com

 

2. 문제

 

11444번: 피보나치 수 6 (acmicpc.net)

 

11444번: 피보나치 수 6

첫째 줄에 n이 주어진다. n은 1,000,000,000,000,000,000보다 작거나 같은 자연수이다.

www.acmicpc.net

 

이미 배운 행렬의 거듭제곱을 구현하고 (1,0)원소를 구하면 된다

 

from sys import stdin

def matrix_multiplication(a,b,mod):
    
    result = [[0,0],[0,0]]

    for i in range(2):
        
        for j in range(2):
            
            for k in range(2):
                
                result[i][j] += a[i][k]*b[k][j]

                result[i][j] %= mod
    
    return result

def matrix_exponentiation(m,n,mod):
    
    result = [[1,0],[0,1]]

    while n > 0:
        
        if n % 2 == 1:
            
            result = matrix_multiplication(result,m,mod)
        
        m = matrix_multiplication(m,m,mod)
        n //= 2
    
    return result

n = int(stdin.readline())

matrix = [[1,1],[1,0]]

mod = 1000000007

result = matrix_exponentiation(matrix,n,mod)

print(result[1][0])

 

 

피보나치 수를 구하는 여러가지 방법 (acmicpc.net)

 

피보나치 수를 구하는 여러가지 방법

피보나치 수는 다음과 같이 정의되는 수열입니다. $F_0 = 0$ $F_1 = 1$ $F_n = F_{n-1} + F_{n-2}$ 피보나치 수를 조금 써보면, 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ... 와 같습니다. 피보나치 수를 구하는 함수

www.acmicpc.net

 

 

피보나치 수열을 구하는 효율적인 방법 (tistory.com)

 

피보나치 수열을 구하는 효율적인 방법

Fibonacci 피보나치 수열이란 첫 번째와 두 번째 항이 1이고 세 번째 항부터는 이전 두 개의 숫자를 더한 점화식을 갖는 수열이다. $$ \begin{align} & F_{i+1} = F_{i} + F_{i-1} \\ & F_{1} = F_{2} = 1 \end{align}$$ 흔

ohgym.tistory.com

 

 

 

TAGS.

Comments