Baekjoon - 피보나치 함수

2025. 1. 19. 23:43·코딩테스트 연습
SMALL

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

 

문제의 조건은 N이 주어졌을 때, fibonacci(N)을 호출했을 때, 0과 1이 각각 몇 번 출력되는지 구하는 프로그램을 작성하는 것이다. 그리고 제한 시간이 0.25초 라는 것을 명심해야 한다.

 

문제에서 주어진 대로 재귀 함수로 구현한다면 시간초과가 뜬다. 

 

찾아보니깐 방법이 두가지가 있었다.

1. 메모이제이션

2. DP(동적프로그래밍)

 

이 글에서는 메모이제이션에 대해서 설명하겠다.

 

피보나치란?

피보나치 수열은 F(n) = F(n-1) + F(n-2)의 형태로, 이전 두 수의 합이 현재 수가 되는 수열입니다.

 

  • 기본 값: F(0) = 0, F(1) = 1
  • 예시: 0, 1, 1, 2, 3, 5, 8, 13, 21, ...

재귀로 구현했을 때 문제점

int fibonacci(int n) {
    if (n == 0) return 0;
    if (n == 1) return 1;
    return fibonacci(n-1) + fibonacci(n-2);
}

 

 

  • 중복 계산 문제: 같은 값을 여러 번 계산하게 됩니다.
  • 예를 들어 F(5)를 계산할 때:
    • F(4)와 F(3)을 계산
    • F(4)는 다시 F(3)와 F(2)를 계산
    • F(3)이 여러 번 중복 계산됨
  • 시간 복잡도: O(2^n)으로 매우 비효율적
  • 해결 방법 메모이제이션

 

 

메모이제이션?

 

한 번 계산한 값을 배열에 저장해두고 재사용하는 방식이다.

  • 중복 계산을 피할 수 있어 효율적
  • 시간 복잡도: O(n)으로 크게 개선
int zero[41]; // 0이 출력되는 횟수를 저장하는 배열
int one[41];  // 1이 출력되는 횟수를 저장하는 배열

void count_fibonacci() {
    // 기본 케이스 초기화
    zero[0] = 1; // f(0)을 호출하면 0이 1번 출력
    one[0] = 0;  // f(0)을 호출하면 1은 0번 출력
    
    zero[1] = 0; // f(1)을 호출하면 0은 0번 출력
    one[1] = 1;  // f(1)을 호출하면 1이 1번 출력
    
    // 다이나믹 프로그래밍으로 값 계산
    for(int i = 2; i <= 40; i++) {
        zero[i] = zero[i-1] + zero[i-2]; // i번째 수에서 0이 출력되는 횟수
        one[i] = one[i-1] + one[i-2];    // i번째 수에서 1이 출력되는 횟수
    }
}

 

 

메모이제이션이 사용된 부분과 원리

  • zero[]와 one[] 배열 자체가 메모이제이션을 구현한 것이다.
  • 각 배열은 특정 n값에 대해 0과 1이 각각 몇 번 출력되는지를 저장한다.
  • 한 번 계산된 값은 배열에 저장되어 있어 재사용된다.
  • 피보나치의 특성을 이용해 현재 값은 이전 두 값의 합으로 계산된다.

예를 들어, f(3)의 경우:

  • zero[3] = zero[2] + zero[1]
  • one[3] = one[2] + one[1] 이런 식으로 이전에 계산해둔 값들을 재사용하여 새로운 값을 계산한다.

 

 

메모이제이션의 작동 방식

  1. 첫 번째 계산
    memo[0] = 0  // 기본값
    memo[1] = 1  // 기본값

  2. 값을 계산하고 저장
    // F(2) 계산
    memo[2] = memo[1] + memo[0]  // 1 저장
    
    // F(3) 계산
    memo[3] = memo[2] + memo[1]  // 2 저장
    
    // F(4) 계산
    memo[4] = memo[3] + memo[2]  // 3 저장

  3. 저장된 값 재사용
    • F(3)이 다시 필요할 때는 계산하지 않고 memo[3]에서 바로 가져옴
    • 마치 계산 결과를 메모장에 적어두고 필요할 때 다시 보는 것과 같음

간단한 비유를 들자면:

  • 메모이제이션이 없을 때: 매번 1+1을 계산하는 것
  • 메모이제이션이 있을 때: 1+1=2라는 것을 메모해두고 다음에는 계산하지 않고 2를 바로 사용

예제 코드:

int memo[100] = {0}; // 결과를 저장할 배열

int fibonacci(int n) {
    // 이미 계산된 값이 있으면 바로 반환
    if (memo[n] != 0) return memo[n];
    
    // 기본 케이스
    if (n <= 1) return n;
    
    // 계산하고 메모에 저장
    memo[n] = fibonacci(n-1) + fibonacci(n-2);
    return memo[n];
}

 

728x90

'코딩테스트 연습' 카테고리의 다른 글

Baekjoon - 어린왕자  (0) 2025.01.19
SW Expert Academy - 22795. 일곱 부하의 평균 D3  (1) 2025.01.13
SW Expert Academy - 2001. 파리 퇴치 D2  (1) 2025.01.10
SW Expert Academy - 1204. 최빈수 구하기 D2  (0) 2025.01.09
SW Expert Academy - 22979. 문자열 옮기기 D3  (0) 2025.01.08
'코딩테스트 연습' 카테고리의 다른 글
  • Baekjoon - 어린왕자
  • SW Expert Academy - 22795. 일곱 부하의 평균 D3
  • SW Expert Academy - 2001. 파리 퇴치 D2
  • SW Expert Academy - 1204. 최빈수 구하기 D2
알파 조
알파 조
공부 일기장
  • 알파 조
    Blue Ocean
    알파 조
  • 전체
    오늘
    어제
    • 분류 전체보기 (93)
      • Algorithm (9)
      • Data Structure (3)
      • Python (7)
      • 컴퓨터 구조 요약 (6)
      • 몰입 교육 (7)
      • JavaScript (1)
      • Vue.js (7)
      • 코딩테스트 연습 (40)
      • SpringBoot (9)
      • 데이터베이스 (2)
  • 블로그 메뉴

    • Home
    • Computer structure
    • Algorithm
    • SpringBoot
    • Vuejs
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    항해99
    MSA 기초
    리그오브레전드 #롤 #LOL #60프레임 버그 #GPU #윈도우10 #롤 60프레임 고정
    티스토리챌린지
    Git
    잔디 기부 캠페인
    오블완
    잔디 기부
    Udemy#Python#Bootcamp#Object and Data Structure Basics
  • hELLO· Designed By정상우.v4.10.3
알파 조
Baekjoon - 피보나치 함수
상단으로

티스토리툴바