Home기술 & 코딩코딩 테스트DP 동적 계획법을 파이썬으로 구현하는 피보나치 수열 백준 2748

DP 동적 계획법을 파이썬으로 구현하는 피보나치 수열 백준 2748

피보나치 수열은 동적 계획법(Dynamic Programming)의 대표적인 학습 예제로, 단순하지만 알고리즘의 핵심 원리를 이해하는데 매우 효과적인 주제이다. 이 글에서는 피보나치 수열의 개념부터 효율적 구현 방법까지 심층적으로 분석하였다.

🔍 동적 계획법의 개념과 원리

동적 계획법은 복잡한 문제를 작은 부분 문제들로 나누어 해결하는 알고리즘 설계 기법이다. 큰 문제를 작은 문제로 분할하여 각 하위 문제의 해를 계산하고, 이를 저장하여 상위 문제를 해결하는 방식으로 작동한다4.

1. 동적 계획법의 핵심 조건

– 동적 계획법을 적용하기 위한 두 가지 필수 조건이 존재한다15.
최적 부분 구조(Optimal Substructure): 큰 문제를 작은 문제로 나눌 수 있어야 한다3.
중복되는 부분 문제(Overlapping Subproblem): 동일한 작은 문제가 반복적으로 등장해야 한다315.

2. 메모리를 통한 효율성 향상

– 동적 계획법은 메모리 공간을 활용하여 연산 횟수를 획기적으로 줄인다13.
– 이미 계산된 결과를 저장하고 재활용함으로써 중복 계산을 방지한다34.
– 이를 통해 시간 복잡도를 크게 개선할 수 있다5.

📊 피보나치 수열 소개

피보나치 수열은 0과 1로 시작하여 이전 두 항의 합으로 다음 항을 결정하는 수열이다8.

1. 피보나치 수열의 정의

수학적 정의: Fn = Fn-1 + Fn-2 (n ≥ 2)
초기값: F0 = 0, F1 = 1
수열: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, …

2. 피보나치 구현의 문제점

– 단순 재귀로 구현할 경우 동일한 계산이 반복되는 심각한 비효율이 발생한다7.
– 예를 들어 F(5)를 구할 때, F(3)이 여러 번 계산되며, 이는 F(n) 값이 증가할수록 기하급수적으로 연산량이 증가한다6.
– F(40)를 단순 재귀로 계산할 경우 무려 10초 이상의 시간이 소요된다7.

💡 동적 계획법 구현 방식

동적 계획법에는 두 가지 주요 구현 방식이 존재한다. 각각의 특징과 장단점을 살펴보자14.

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

1. 하향식(Top-down) 접근: 메모이제이션

메모이제이션(Memoization)은 이미 계산한 값을 메모리에 저장하여 재활용하는 기법이다5.

작동 원리:
– 큰 문제에서 작은 문제로 분할하며 재귀적으로 접근한다6.
– 계산된 결과를 캐시(배열 등)에 저장하고 중복 계산을 방지한다56.
– 필요한 부분 문제만 계산하는 ‘레이지 밸류에이션(Lazy Evaluation)’ 특성을 가진다.

파이썬 코드 구현:

cache = [-1] * 91
cache[0] = 0
cache[1] = 1

def f(n):
    if cache[n] == -1:
        cache[n] = f(n-1) + f(n-2)
    return cache[n]
    
print(f(int(input())))

2. 상향식(Bottom-up) 접근: 타뷸레이션

타뷸레이션(Tabulation)은 작은 문제부터 순차적으로 해결하며 테이블을 채우는 방식이다5.

작동 원리:
– 가장 작은 부분 문제부터 시작하여 큰 문제로 확장한다10.
– 반복문을 사용하여 모든 부분 문제를 차례대로 계산한다5.
– 재귀 호출을 사용하지 않아 스택 오버플로우 위험이 없다5.

파이썬 코드 구현:

N = int(input())
cache = [-1] * 91
cache[0] = 0
cache[1] = 1

for i in range(2, N+1):
    cache[i] = cache[i-1] + cache[i-2]
    
print(cache[N])

📈 시간복잡도 및 성능 비교

두 구현 방식의 효율성과 성능을 비교해보자.

1. 단순 재귀 vs 동적 계획법

단순 재귀: O(2^n)의 시간복잡도를 가진다7.
– F(40) 계산 시 약 10억 번 이상의 연산 필요7.
– F(90) 계산은 현실적으로 불가능한 수준의 연산량 발생7.

동적 계획법(메모이제이션): O(n)의 시간복잡도79.
– F(30) 계산 시 단 59번 정도의 함수 호출만 발생7.
– F(90) 계산도 즉시 처리 가능7.

2. 메모이제이션 vs 타뷸레이션

메모이제이션 장점:
– 필요한 부분 문제만 계산하여 불필요한 연산을 줄인다14.
– 문제 구조를 직관적으로 이해하기 쉽다10.

타뷸레이션 장점:
– 재귀 호출이 없어 더 빠르게 동작한다10.
– 메모리를 더 효율적으로 사용할 수 있다510.
– 스택 오버플로우 위험이 없다5.

🛠️ 피보나치 구현 시 고려사항

실제 코딩 시 주의해야 할 점과 최적화 방안을 살펴보자.

1. 오버플로우 처리

– 피보나치 수열은 n이 커질수록 값이 급격히 증가한다78.
– 언어별 정수 범위를 초과할 수 있으므로 큰 수 처리가 필요하다.
– 파이썬은 자동으로 큰 정수를 처리하지만, 다른 언어는 별도 처리가 필요하다.

2. 공간 복잡도 최적화

슬라이딩 윈도우 기법:
– 피보나치 계산 시 모든 중간값을 저장할 필요가 없다10.
– 최근 두 값만 유지하면 O(1)의 공간복잡도로 구현 가능하다.

def fibonacci_optimized(n):
    if n <= 1:
        return n
    a, b = 0, 1
    for _ in range(2, n+1):
        a, b = b, a+b
    return b

3. 응용 사례: 함수 호출 횟수 계산

– 피보나치 함수 호출 시 0과 1의 호출 패턴도 피보나치 수열을 따른다912.
– 이를 활용한 백준 1003번 문제 해결 방법:

def fibo_count(n):
    zero = [1, 0]
    one = [0, 1]
    
    for i in range(2, n+1):
        zero.append(zero[i-1] + zero[i-2])
        one.append(one[i-1] + one[i-2])
        
    return zero[n], one[n]

📚 결론 및 학습 포인트

동적 계획법은 알고리즘 문제 해결의 핵심 기법으로, 피보나치 수열은 이를 학습하기 위한 완벽한 예제이다.

1. 동적 계획법의 가치

– 중복 계산을 효율적으로 제거하여 기하급수적인 성능 향상을 이끌어낸다57.
– 단순한 메모리 활용으로 시간복잡도를 O(2^n)에서 O(n)으로 개선한다7.
– 알고리즘 설계에서 시간과 공간의 트레이드오프를 잘 보여주는 예시이다6.

2. 실전 활용 팁

– 문제를 작은 부분으로 나누는 방법을 먼저 고민하라34.
– 부분 문제 간의 관계(점화식)를 명확히 정의하라14.
– 메모이제이션과 타뷸레이션 중 문제 특성에 맞는 방식을 선택하라10.
– 상태 공간을 최소화하여 메모리 효율성을 높이는 방법을 고려하라10.

3. 학습 경로 제안

– 피보나치 수열 → 최장 증가 부분 수열(LIS) → 배낭 문제(Knapsack) → 편집 거리(Edit Distance)
– 점점 복잡한 DP 문제로 확장하며 접근 방식의 패턴을 익히는 것을 권장한다.

texttimeline 1202 : 피보나치 수열 최초 소개 (레오나르도 피보나치) 1950년대 : 동적 계획법 개념 확립 (리처드 벨만) 1960년대 : 컴퓨터 과학에 DP 적용 시작 2000년대 : 알고리즘 인터뷰 및 경진대회에서 필수 주제로 자리매김

동적 계획법은 단순히 알고리즘 기법을 넘어 문제 해결의 사고방식을 변화시키는 패러다임이다. 피보나치 수열의 단순한 예제를 통해 DP의 강력함을 경험하고, 더 복잡한 문제에도 이 원리를 적용해 보길 권장한다.

Citations:

  1. https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/attachments/56096911/6bb6f2f7-ef84-4d9a-a867-92db28f4a152/paste.txt
  2. https://www.acmicpc.net/problem/2748
  3. https://velog.io/@gillog/%EB%8F%99%EC%A0%81-%EA%B3%84%ED%9A%8D%EB%B2%95Dynamic-Programming
  4. https://wikidocs.net/120406
  5. https://gimmesome.tistory.com/258
  6. https://5-ssssseung.tistory.com/32
  7. https://cryptosalamander.tistory.com/172
  8. https://cheonjoosung.github.io/blog/java-fibo
  9. https://j-ungry.tistory.com/150
  10. https://blog.naver.com/jinhan814/222603789811
  11. https://hongjw1938.tistory.com/47
  12. https://dduniverse.tistory.com/entry/%EB%B0%B1%EC%A4%80-1003-DP-%ED%94%BC%EB%B3%B4%EB%82%98%EC%B9%98-%ED%95%A8%EC%88%98-%ED%8C%8C%EC%9D%B4%EC%8D%AC-python
  13. https://velog.io/@hosunghan0821/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%8F%99%EC%A0%81-%EA%B3%84%ED%9A%8D%EB%B2%95Dynamic-Programming-DP-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC
  14. https://jeongwoo.tistory.com/88
  15. https://didu-story.tistory.com/220
  16. https://velog.io/@bonjaski0989/%EB%8F%99%EC%A0%81%EA%B3%84%ED%9A%8D%EB%B2%95Dynamic-Programming-%EC%A0%95%EB%A6%AC%EA%B8%80Python
  17. https://80000coding.oopy.io/60c3d4d3-f569-4b47-bdde-9a65d30f3bc5
  18. https://star-crab.tistory.com/27
  19. https://devvvyang.tistory.com/15
  20. https://ai-sinq.tistory.com/entry/%EB%8F%99%EC%A0%81-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-Dynamic-Programming-DP
  21. https://devraphy.tistory.com/627
  22. https://codeinleonis.tistory.com/28
  23. https://blog.naver.com/je_un/222109393673
  24. https://galid1.tistory.com/507
  25. https://blog.junu.dev/14
  26. https://velog.io/@minzyaaaaaa/%EB%8F%99%EC%A0%81-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%EB%A9%94%EB%AA%A8%EC%9D%B4%EC%A0%9C%EC%9D%B4%EC%85%98%EA%B3%BC-%ED%83%80%EB%B7%B8%EB%A0%88%EC%9D%B4%EC%85%98
  27. https://9-coding.tistory.com/entry/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Dynamic-Programming-%EB%8F%99%EC%A0%81-%EA%B3%84%ED%9A%8D%EB%B2%95
  28. https://velog.io/@boyeon_jeong/%EB%8F%99%EC%A0%81%EA%B3%84%ED%9A%8D%EB%B2%95Dynamic-Programming
  29. https://velog.io/@hope1213/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%8F%99%EC%A0%81%EA%B3%84%ED%9A%8D%EB%B2%95-Dynamic-Programming-DP
  30. https://guard-x100.tistory.com/19
  31. https://wikidocs.net/130632
  32. https://velog.io/@minjae-mj/Memoization-%EB%A9%94%EB%AA%A8%EC%9D%B4%EC%A0%9C%EC%9D%B4%EC%85%98-feat.-%ED%94%BC%EB%B3%B4%EB%82%98%EC%B9%98-%EC%88%98%EC%97%B4
  33. https://infinitt.tistory.com/220
  34. https://wikidocs.net/206430
  35. https://aytekin.tistory.com/29
  36. https://velog.io/@jejualrock/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%A9%94%EB%AA%A8%EC%9D%B4%EC%A0%9C%EC%9D%B4%EC%85%98
  37. https://velog.io/@cosmos/BOJ%EB%B0%B1%EC%A4%80-2748-python
  38. https://velog.io/@kimdukbae/%EB%8B%A4%EC%9D%B4%EB%82%98%EB%AF%B9-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-Dynamic-Programming
  39. https://cdragon.tistory.com/entry/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0%EC%99%80-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Dynamic-Programming%EB%8F%99%EC%A0%81%EA%B3%84%ED%9A%8D%EB%B2%95
  40. https://hongku.tistory.com/161
  41. https://roamingman.tistory.com/33
  42. https://wooono.tistory.com/515
RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

Recent Comments