[백준] 1003번 피보나치 함수 파이썬

그린·2023년 4월 4일
0

백준

목록 보기
34/44
post-thumbnail

[백준] 1003번 피보나치 함수


✔️문제

분류

다이나믹 프로그래밍(dp)

문제 설명

다음 소스는 N번째 피보나치 수를 구하는 C++ 함수이다.

int fibonacci(int n) {
    if (n == 0) {
        printf("0");
        return 0;
    } else if (n == 1) {
        printf("1");
        return 1;
    } else {
        return fibonacci(n‐1) + fibonacci(n‐2);
    }
}

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
input = sys.stdin.readline
t = int(input())
def fibo(n, arr):
  if n == 0 or n==1:
    arr[n] += 1
    return arr
  else:
    return fibo(n-1,arr) + fibo(n-2,arr)
for _ in range(t):
  arr = [0, 0]
  fibo(int(input()), arr)
  print(arr[0], arr[1])

fibo 함수를 만들어 호출 횟수를 구했다.

  1. 입력받은 수와 arr를 인자로 보낸다.
  2. 인자로 받은 n이 0이거나 1이면 해당 인덱스에 1을 더해주면서 호출 횟수를 계산한다.
  3. 0이나 1이 아니라면 피보나치 n-1과 n-2를 통해 0이나 1이 될 때까지 반복하면서 호출 횟수를 계산한다.
  4. arr를 반환해 0과 1의 호출 횟수를 출력한다.

위 코드는 이미 계산한 값도 다시 계산하기 때문에 메모리제이션을 사용해서 다시 작성했다.

✅맞은 코드

import sys
input = sys.stdin.readline
t = int(input())
arr = [[0,0] for i in range(40)]
arr[0] = [1,0]
arr[1] = [0,1]
def fibo(x, arr):
  if arr[x-1] == [0,0]:
    arr[x-1] = fibo(x-1, arr)
  if arr[x-2] == [0,0]:
    arr[x-2] = fibo(x-2, arr)
  return [a+b for a,b in zip(arr[x-1],arr[x-2])]
    
for _ in range(t):
  x=int(input())
  if x==1 or x==0:
    print(arr[x][0], arr[x][1])
  else:
    ans = fibo(x, arr)
    print(ans[0], ans[1])
  1. 인덱스 40까지 2차원 배열을 생성한다.
  2. 1이나 0이라면 바로 배열의 값을 출력한다.
  3. 아니라면 fibo 함수를 실행한다.
  4. 아직 계산된 적이 없다면 즉, 배열의 값이 [0,0]이라면 fibo함수를 호출하고 아니라면 배열에 저장된 값으로 호출 횟수를 계산한다.
  5. 계산한 호출 횟수를 출력한다.

0개의 댓글