알고리즘

BOJ: 피보나치 함수(1003) [C++]

avocado8 2024. 3. 7. 14:47

https://www.acmicpc.net/problem/1003

 

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

 

입력

첫째 줄에 테스트 케이스의 개수 T가 주어진다.

각 테스트 케이스는 한 줄로 이루어져 있고, N이 주어진다. N은 40보다 작거나 같은 자연수 또는 0이다.

 

출력

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

 

 

순환으로 구현한 피보나치 수열 코드가 제시되어 있고 이때 몇 번이나 재호출되는지 세어보라는 문제

여담으로 저 코드의 시간복잡도는 2의n승으로 매우 크다

그러니 저걸 그대로 따라쳐서 횟수를 세라는 건 절대 아닌.. 그런 문제다 애초에 제한시간도 0.25초(추가시간없음.) 이래놓은것을 보면...

 

n=2이면

n=2에서 fib(1) + fib(0)

해서 fib(0) 1번 fib(1) 1번이 호출된다

 

n=3이면

n=3에서 fib(2) + fib(1)

fib(2)에서 fib(1) + fib(0)

해서 fib(0) 1번 fib(1) 2번이 호출된다

 

n=4이면

n=4에서 fib(3) + fib(2)

fib(3)에서 fib(0) 1번 fib(1) 2번

fib(2)에서 fib(0) 1번 fib(1) 1번

...

즉 이전의 계산값을 저장해두고 구해주면 되는것

그럴 때 다이나믹프로그래밍이라는 걸 쓸 수 있었지...

 

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;
typedef pair<int, int>ci;

ci solution(int n) {
	if (n == 0) return { 1,0 };
	if (n == 1) return { 0,1 };
	vector<ci>dp(n+1, { 0,0 });
	dp[0] = { 1, 0 };
	dp[1] = { 0, 1 };
	for (int i = 2; i < n+1; i++) {
		dp[i].first = dp[i - 1].first + dp[i - 2].first;
		dp[i].second = dp[i - 1].second + dp[i - 2].second;
	}
	return dp[n];
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	int t;
	cin >> t;
	for (int i = 0; i < t; i++) {
		int n;
		cin >> n;
		ci res = solution(n);
		cout << res.first << ' ' << res.second << "\n";
	}
	
	return 0;
}

 

그냥 이전 값들을 더해주기만 하면 해결된다

결과값 벡터 초기화할때 n+1로 해줘야 하는 점에서 주의...

 

'알고리즘' 카테고리의 다른 글

BOJ: 크리스마스 선물(14235) [C++]  (0) 2024.03.18
BOJ: 꽃길(14620) [C++]  (0) 2024.03.12
BOJ: 프린터 큐(1966) [C++]  (0) 2024.03.06
BOJ: 스도쿠(2580) [C++]  (0) 2024.03.05
BOJ: 뱀(3190) [C++]  (0) 2024.03.05