프로그래밍/백준

[알고리즘] 백준 1003 파이썬 - 피보나치 함수

매 석 2022. 11. 20. 15:04
반응형

 

 

1003번: 피보나치 함수

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

www.acmicpc.net

 

문제

다음 소스는 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이 각각 몇 번 출력되는지 구하는 프로그램을 작성하시오.

 

문제풀이

dp=[None]*41
dp[0]=[1,0]
dp[1]=[0,1]
t=int(input())
for i in range(t):
    a = int(input())
    if a==0 or a==1:
        print(*dp[a])
    else:
        for j in range(2,a+1):
            dp[j]=[dp[j-1][1],dp[j-1][0]+dp[j-1][1]]
        print(*dp[a])
            
'''
0 : 1 0 
1 : 0 1
2 : 1 1
3 : 1 2
4 : 2 3 
5 : 3 5 
6 : 5 8 
7 : 8 13
8 : 13 21 
9: 21 34
'''

- 문제의 핵심은 다이나믹 프로그래밍 즉 점화식을 찾는 것이다.

- 해당 문제의 규칙을 찾아보면 2부터 dp[j]=[dp[j-1][1],dp[j-1][0]+dp[j-1][1]]라는

  규칙이 반복되는 것을 확인할 수 있다.

- 그렇기에 0과 1의 값만 추가해주고, 2부터는 for문을 돌려가며 a값에 해당하는 값을 찾으면 된다.

 

+ 참고로 for문을 통해 dp[a]값이 이미 그전에 구한 상태라면 바로 출력될 수 있게

   조건문을 넣을 수도 있다. 하지만 이번 문제에서는 시간이 충분하기에

   따로 넣지는 않았다.