행렬을 이용한 피보나치 수열 문제의 해법
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
'알고리즘 > 선형대수학 알고리즘' 카테고리의 다른 글
reduced row echelon form을 구하는 Gauss-Jordan elimination 구현하기 (0) | 2023.09.21 |
---|---|
파이썬으로 두 행렬 곱하기 구현하는 방법 (0) | 2023.03.13 |