DP : 백준 1003 파이썬 문제풀이

보현·2023년 3월 4일
0

알고리즘

목록 보기
1/3

문제

문제링크

fibonacci(3)을 호출하면 다음과 같은 일이 일어난다.

fibonacci(3)은 fibonacci(2)와 fibonacci(1) (첫 번째 호출)을 호출한다.
fibonacci(2)는 fibonacci(1) (두 번째 호출)과 fibonacci(0)을 호출한다.
두 번째 호출한 fibonacci(1)은 1을 출력하고 1을 리턴한다.
fibonacci(0)은 0을 출력하고, 0을 리턴한다.
fibonacci(2)는 fibonacci(1)과 fibonacci(0)의 결과를 얻고, 1을 리턴한다.
첫 번째 호출한 fibonacci(1)은 1을 출력하고, 1을 리턴한다.
fibonacci(3)은 fibonacci(2)와 fibonacci(1)의 결과를 얻고, 2를 리턴한다.
1은 2번 출력되고, 0은 1번 출력된다. N이 주어졌을 때, fibonacci(N)을 호출했을 때, 0과 1이 각각 몇 번 출력되는지 구하는 프로그램을 작성하시오.

//입력
첫째 줄에 테스트 케이스의 개수 T가 주어진다.

각 테스트 케이스는 한 줄로 이루어져 있고, N이 주어진다. N은 40보다 작거나 같은 자연수 또는 0이다.

//출력
각 테스트 케이스마다 0이 출력되는 횟수와 1이 출력되는 횟수를 공백으로 구분해서 출력한다.

정답코드

import sys
T=int(sys.stdin.readline())

# 0,1의 출력횟수를 저장하는 리스트 2개 생성, 초기값
# N은 최대 40이므로 40번 인덱스까지 필요하다
d=[0]*41
d[0],d[2]=1,1

d1=[0]*41
d1[1],d1[2]=1,1

# 0,1의 개수도 피보나치 수열대로 증가
for i in range(3,41):
    d[i]=d[i-2]+d[i-1]
    d1[i]=d1[i-2]+d1[i-1]

for v in range(T):
    n=int(sys.stdin.readline())
    print(d[n],d1[n])

일반적인 피보나치로 풀게 되면 예제에 있는 22정도는 바로 출력이 됐는데 입력값이 30만 해도 0 출력은 50만, 1 출력은 80만이 넘어버려서 시간초과로 틀리게 된다

틀린 코드 일부

def fibo(n):
    if n==0:
        d[0]+=1
        return 0
    elif n==1:
        d[1]+=1
        return 1
    else:
        return fibo(n-2)+fibo(n-1)

이렇게 코드를 짰다. d만 넣는다고 다이나믹 프로그래밍이 아니었다는걸 이번 기회에 확실히 알았다. 저게 전형적인 피보나치 였다.

시간복잡도

재귀함수를 통해 구현한 피보나치 수열의 시간복잡도는 O(N^2) 이라고 한다. 따라서 이러한 문제에서는 반드시 메모이제이션을 사용해야 한다.

메모이제이션을 이용하면 필요한 값을 매번 계산하지 않고 리스트에 저장해 두었다가 불러와 계산하게 되므로 시간복잡도가 O(N)으로 줄게 된다.

참고한 시간복잡도 계산법 링크

profile
노션정리

0개의 댓글