CodingTest/algorithm

[DP] Dynamic Programming 알고리즘 알아보기

사족보행 개발자 2024. 11. 10. 22:36
728x90

 

오늘은 거두절미하고, DP(Dynamic Programming) 알고리즘에 대해서 알아보고자 한다.

여기서 설명하는 DP 알고리즘은 동적 할당과는 다른 개념이므로, 착각하지 말자

동적할당은 메모리 공간에 동적으로 (런타임에) 변수 공간을 할당한다는 개념이며,

동적이라는 것 자체가 프로그램이 실행되는 런타임에 발생한다는 것을 이해하면 된다.

 

DP 알고리즘을 설명할 때 주로 피보나치 수열을 예시로 들곤 한다.

피보나치 수열은 특정 점화식으로 반복되는 수열을 의미한다.

점화식은 아래와 같다.

 

F(n) = F(n-1) + F(n-2), 단 F(0) = 0, F(1) = 1

 

이러한 피보나치 수열을 코드로 구현한다면 어떨까?

 

# 재귀를 사용한 피보나치 수열 구현
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

 

코드는 매우 간단하게 구현할 수 있다.

 

하지만, 만약 피보나치 수열의 1000번째 숫자를 알아내고자 한다면, 

위 코드로는 얼마나 걸릴까?

 

해당 코드는 O(2^n)이라는 시간복잡도를 갖고 있다.

따라서 현 컴퓨터 구조로는 우리의 수명이 다할 때까지도 계산을 마칠 수 없을 것이다.

 

이러한 경우에 사용되는게 DP 알고리즘이다.

DP알고리즘을 적용할 수 있는 문제의 특징을 2가지가 있다.

 

1. 큰 문제를 작은 문제로 나눌 수 있다.

2. 작은 문제로 구한 정답은 그것을 포함하는 큰 문제에서도 정답이 달라지지 않는다.

 

피보나치 수열이 위 조건을 만족하는 대표적인 문제이다.

이 문제를 Memoization(메모이제이션) 기법을 활용하여 해결해보자.

(메모이제이션 기법은 저장한 정보를 그대로 가져와서 사용한다는 점에서 caching 이라고도 불린다.)

 

# 메모이제이션을 사용한 피보나치 수열 구현 (Top-Down 방식)
memo = {}

def fibonacci_memo(n):
    if n <= 1:
        return n
    if n not in memo:
        memo[n] = fibonacci_memo(n-1) + fibonacci_memo(n-2)
    return memo[n]

 

위 코드로 수행하면 O(N)의 시간복잡도로 문제를 빠르게 해결할 수 있음을 알 수있다.

이렇게 다이나믹 프로그래밍이란 큰 문제를 작게 나누고, 같은 문제라면 한 번씩만 풀어서

문제를 효육적으로 해결하는 알고리즘 기법이다.

 

여기서 추가적으로 재귀함수 방식으로 DP를 구현하게 된다면, 

컴퓨터 시스템에서는 함수를 다시 호출했을 때 메모리 상에 적재되는 오버헤드가 발생할 수 있다.

 

따라서 재귀함수 대신에 반복문으로 구현하게 된다면 오버헤드를 줄일 수 있다.

 

## 반복문으로 구현한 피보나치 ##

# 반복문을 사용한 피보나치 수열 구현 (Bottom-Up 방식)
def fibonacci_iterative(n):
    if n <= 1:
        return n
    prev, curr = 0, 1
    for _ in range(2, n + 1):
        prev, curr = curr, prev + curr
    return curr

 

이 방식은 스택 오버헤드를 피할 수 있으며, 같은 시간복잡도 O(n)으로 문제를 해결할 수 있다.

이처럼 동적 계획법에는 두 가지 접근 방식이 있다:

  • Top-Down 방식: 큰 문제를 해결하기 위해 작은 문제를 재귀적으로 호출하는 방식. 메모이제이션을 통해 중복 계산을 줄인다.
  • Bottom-Up 방식: 작은 문제부터 시작해 차례로 답을 쌓아올려 큰 문제를 해결하는 방식. 반복문을 사용해 구현한다.

동적 계획법은 큰 문제를 작게 나누고,

작은 문제를 한 번만 풀어 중복 계산을 방지함으로써 효율적으로 문제를 해결하는 알고리즘 기법이다.

 

다음 번에는 DP를 적용할 수 있는 더 다양한 문제와 그 해결 방법에 대해 살펴보자.

 

728x90