다음 소스는 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)을 호출하면 다음과 같은 일이 일어난다.
첫째 줄에 테스트 케이스의 개수 T가 주어진다.
각 테스트 케이스는 한 줄로 이루어져 있고, N이 주어진다. N은 40보다 작거나 같은 자연수 또는 0이다.
각 테스트 케이스마다 0이 출력되는 횟수와 1이 출력되는 횟수를 공백으로 구분해서 출력한다.
다이나믹 프로그래밍 문제이다.
다이나믹 프로그래밍이란 큰 문제를 작은 문제로 쪼개어 푸는 방식으로, Divide and Conquer 과의 차이점은 DP는 작은 문제가 계속적으로 반복 된다는 점이다. 따라서 반복 되는 값을 저장해두었다가(Memoization) 이를 이용하는 것이다.
피보나치 수열은 대표적인 DP 문제이다.
본 문제에서는 0과 1의 출력이 호출되는 횟수를 알고자하였다.
0과 1이 출력된 횟수를 DP 배열로 미리 저장하여 문제를 해결하였다.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int DP[40][2] = { 0 };
int main() {
int T;
int max;
vector<int> n;
cin >> T;
for (int i = 0; i < T; i++) {
int temp;
cin >> temp;
n.push_back(temp);
}
max = *max_element(n.begin(), n.end());
DP[0][0] = 1;
DP[0][1] = 0;
DP[1][0] = 0;
DP[1][1] = 1;
for (int i = 2; i <= max; i++) {
DP[i][0] = DP[i - 2][0] + DP[i - 1][0];
DP[i][1] = DP[i - 2][1] + DP[i - 1][1];
}
for (int i = 0; i < T; i++) {
cout << DP[n[i]][0] << " " << DP[n[i]][1] << "\n";
}
return 0;
}