다음 소스는 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)을 호출하면 다음과 같은 일이 일어난다.
1은 2번 출력되고, 0은 1번 출력된다. N이 주어졌을 때, fibonacci(N)을 호출했을 때, 0과 1이 각각 몇 번 출력되는지 구하는 프로그램을 작성하시오.
첫째 줄에 테스트 케이스의 개수 T가 주어진다.
각 테스트 케이스는 한 줄로 이루어져 있고, N이 주어진다. N은 40보다 작거나 같은 자연수 또는 0이다.
각 테스트 케이스마다 0이 출력되는 횟수와 1이 출력되는 횟수를 공백으로 구분해서 출력한다.
3
0
1
3
1 0
0 1
1 2
동적 계획법은 주로 2 단계에 걸쳐서 해결할 수 있다.
위의 fibonacci 함수를 3까지 실행했을 때 함수가 실행되는 과정이다.
f(2)가 f(0), f(1)의 트리 구조를 가지고 있고, f(3)가 f(1), f(2)의 트리 구조를 가지고 있다. 따라서 f(2)에서는 각각 0, 1이 한 번씩 출력되며, f(3)에서는 f(1)과 f(2)의 출력 횟수의 합인 0이 1번, 1이 2번 출력된다.
이를 바탕으로 다음과 같은 점화식을 세울 수 있다.
f(n) = f(n - 1) + f(n - 2)
t = int(input())
dp = [0] * 41
# dp 테이블 생성
dp[0] = (1, 0)
dp[1] = (0, 1)
for _ in range(t):
n = int(input())
for i in range(2, n + 1):
# -1한 값과 -2한 값의 트리를 가지게 됨
dp[i] = (dp[i - 1][0] + dp[i - 2][0], dp[i - 1][1] + dp[i - 2][1])
print(dp[n][0], dp[n][1])
점화식을 바탕으로 코드로 표현하면 다음과 같다.