728x90
http://www.acmicpc.net/problem/11444
# 조건
- 피보나치 수는 0과 1로 시작한다.
- 0번째 피보나치 수는 0이고, 1번째 피보나치 수는 1이다.
- 그 다음 2번째 부터는 바로 앞 두 피보나치 수의 합이 된다.
- 이를 식으로 써보면 Fn = Fn-1 + Fn-2 (n ≥ 2)가 된다.
- n=17일때 까지 피보나치 수를 써보면 다음과 같다.
- 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597
- n이 주어졌을 때, n번째 피보나치 수를 구하는 프로그램을 작성하시오.
# 접근 방법
- dp를 이용하여 풀었던 이전 문제들과는 다르게 입력값이 어마어마하여
- O(logn)의 알고리즘으로 풀어주어야 한다.
- 행렬과 피보나치 사이에는 아래 그림과 같은 관계가 존재한다.
- 즉 위 행렬의 n제곱만 구한다면 피보나치 수를 구할 수 있다.
import sys
input = sys.stdin.readline
n, B = 2, int(input())
A = [[1,1],[1,0]]
def power(a,b,n):
cal = []
for i in range(n):
temp = []
for j in range(n):
num = 0
for k in range(n):
num += a[i][k] * b[k][j]
temp.append(num%1000000007)
cal.append(temp)
return cal
# 행렬의 곱셉을 함수화 해보았다.
def dac(s,b):
if b == 1:
return s
a = dac(s,b//2)
cal = power(a,a,n)
result = []
if b % 2:
result = power(cal,A,n)
else:
result = cal
return result
print(dac(A,B)[0][1])
728x90
'ALGORITHM > 분할정복' 카테고리의 다른 글
[백준 12850번] 파이썬 - 본대 산책2 (0) | 2023.04.29 |
---|---|
[백준 13172번] 파이썬 - ∑ (시그마) (1) | 2022.12.31 |
[백준 10830번] 파이썬 - 행렬 제곱 (0) | 2022.12.24 |
[백준 1992번] 파이썬 - 쿼드트리 (0) | 2022.10.09 |
[백준 2630번] 파이썬 - 색종이 만들기 (1) | 2022.10.08 |