본문 바로가기

BAEKJOON/다이나믹 프로그래밍

백준 1003번 [피보나치 함수](C++)-yes6686- 티스토리

728x90
SMALL

백준 문제 풀이: 1003 [피보나치 함수]


문제 링크: https://www.acmicpc.net/problem/1003

문제 설명:

피보나치 수열에서 \( F(0) = 0 \), \( F(1) = 1 \), \( F(n) = F(n-1) + F(n-2) \)로 정의됩니다. 이때 \( F(n) \)을 계산할 때 호출되는 0과 1의 개수를 구하는 문제입니다.


문제 해결 코드


#include <iostream>
using namespace std;

long long int zeroCntDp[41];
long long int oneCntDp[41];

// 0이 호출된 횟수 계산
long long int zeroCntFibo(int n) {
    if (zeroCntDp[n] != -1) return zeroCntDp[n];
    if (n == 0) {
        return zeroCntDp[n] = 1;
    } else if (n == 1) {
        return zeroCntDp[n] = 0;
    } else {
        return zeroCntDp[n] = zeroCntFibo(n - 1) + zeroCntFibo(n - 2);
    }
}

// 1이 호출된 횟수 계산
long long int oneCntFibo(int n) {
    if (oneCntDp[n] != -1) return oneCntDp[n];
    if (n == 0) {
        return oneCntDp[n] = 0;
    } else if (n == 1) {
        return oneCntDp[n] = 1;
    } else {
        return oneCntDp[n] = oneCntFibo(n - 1) + oneCntFibo(n - 2);
    }
}

int main() {
    // DP 배열 초기화
    for (int i = 0; i < 41; i++) {
        zeroCntDp[i] = -1;
        oneCntDp[i] = -1;
    }

    int T;
    cin >> T;
    while (T--) {
        int x;
        cin >> x;
        cout << zeroCntFibo(x) << ' ' << oneCntFibo(x) << '\n';
    }

    return 0;
}

코드 설명

  • 핵심 알고리즘: 동적 프로그래밍(DP)을 사용하여 피보나치 함수 호출에서 0과 1의 호출 횟수를 미리 계산합니다.
  • 점화식:
    • zeroCntDp[n] = zeroCntDp[n-1] + zeroCntDp[n-2]
    • oneCntDp[n] = oneCntDp[n-1] + oneCntDp[n-2]
  • 구현 세부사항:
    • DP 배열을 사용하여 호출 횟수를 저장
    • 재귀적으로 값을 계산하며 중복 계산 방지
  • 시간 복잡도: O(n) (각 테스트 케이스에서 최대 40까지 계산)
    • DP 배열을 활용해 중복 계산 방지

결과

피보나치 수열 계산 시 호출된 0과 1의 횟수를 정확히 계산합니다. 동적 프로그래밍을 활용하여 효율적으로 문제를 해결했습니다.

다른 접근 방식이나 개선 사항이 있다면 댓글로 공유 부탁드립니다!

728x90
LIST