알고리즘/Dynamic Programming
BOJ) 1003. 피보나치 함수 ( C / C++)
KIBBOMI
2019. 12. 21. 00:08
1. 문제 링크
https://www.acmicpc.net/problem/1003
1003번: 피보나치 함수
각 테스트 케이스마다 0이 출력되는 횟수와 1이 출력되는 횟수를 공백으로 구분해서 출력한다.
www.acmicpc.net
2. 문제 개요
피보나치 함수 재귀 호출에 의하여 (0)과 (1)이 몇 번 호출되는지 세는 프로그램 구현.
3. 문제 힌트!! ( 힌트만 보고 다시 구현해보세요. )
dp배열을 만들 때 0과 1이 따로들어가도록 2개 선언하기.
기존의 피보나치 함수는 값을 반환했는데(0에서 0, 1에서 1), 이번에는 0의 개수, 1의 개수를 반환하기.
4. 문제 풀이
피보나치 함수에서 반환 할 때 pair를 사용했습니다.
pair <int, int> dp[n]은 입력되는 수가 n일 때의 0과 1이 호출되는 횟수를 가지고 있도록 구현하였습니다.
n값이 증가되어 갈 때 정확한 수열의 값을 알 필요는 없습니다. 다만 n일 때 0과 1이 몇 번 호출되는지만 기억해나가면서 문제를 풀었습니다.
전체적인 틀은 기존의 피보나치 함수값 구하는 문제와 동일합니다.
5. 코드
#include <cstdio>
#include <algorithm>
using namespace std;
// pair<0, 1>. dp[n]으로 n에서 0과 1이 몇번 발생하는지
pair<int, int> dp[41];
pair<int,int> fibo(int n)
{
//finish condition
if (n == 0) return make_pair(1, 0);
if (n == 1) return make_pair(0, 1);
//memoization
if (dp[n].first != 0 && dp[n].second != 0) return dp[n];
pair<int, int> left = fibo(n - 1);
pair<int, int> right = fibo(n - 2);
return dp[n] = make_pair(left.first + right.first, left.second + right.second);
}
int main(void)
{
//초기값
dp[0].first = 1;
dp[1].second = 1;
//40까지 그냥 계산
fibo(40);
int t;
scanf("%d", &t);
while (t--)
{
int n;
scanf("%d", &n);
printf("%d %d\n", dp[n].first, dp[n].second);
}
return 0;
}
지적, 댓글 언제나 환영입니다~