B)1003

오두호·2022년 4월 27일
0

Algorithm

목록 보기
19/27
post-thumbnail

피보나치 함수

문제

다음 소스는 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이 출력되는 횟수를 공백으로 구분해서 출력한다.

DP라는 개념에 대해 공부하면, 가장 먼저 나오는 예시 문제인 피보나치 수열이다.
DP는, 동적 계획법 이라고도 하며, 분할 정복 기법으로 어떤 문제를 풀게 될 경우에, 어떤 부분에서, 같은 문제를 계속 풀게 되면서, 발생하는 비효율적인 부분을 개선하고자, 한 문제는, 한 번만 풀자. 라는 목적을 가진 알고리즘이라고 생각한다.
큰 문제를, 여러가지 작은 문제로 나눌 수 있을 때, 그리고 작은 문제에서 푼 정답이 큰 문제를 풀 때도 동일할 경우, 이를 적어놓는 메모이제이션 이라는 기법을 통하여, 결과를 저장한 후, 그 결과가 필요할 경우 계속 다시 계산하는 것이 아닌, 적어둔 것을 보고 결과를 가져오는 식으로 불필요한 계산을 줄이는 방법이다.
메모이제이션 이라는 기술이 가장 핵심적인 부분이고, 관련된 많은 문제를 풀어봐야 한다고 생각한다.

구현(DP)
피보나치 수열: D[i] = D[i-1]+ D[i-2]
이전 값을 저장해두고, 이를 다음 결과에 사용

import sys
T = int(input())
for i in range(T):
    n = int(sys.stdin.readline())
    count0 = 1
    count1 = 0
    temp = 0
    for _ in range(n):
        temp = count1
        count1 = count1 + count0
        count0 = temp
    print(count0, count1)

꽤 간단하게 풀 수 있는 문제였다.

profile
Developer

0개의 댓글