Dev/Algorithm

DP(Dynamic Programming)

마이캣호두 2025. 2. 7. 20:32
반응형

동적 계획법(DP, Dynamic Programming)은 복잡한 문제를 해결하기 위해 그 문제를 더 작은 부분 문제로 나누고, 각 부분 문제를 한 번만 해결하여 그 결과를 저장하고 재사용하는 방법론입니다. DP는 주로 중복된 계산을 피하고 문제를 효율적으로 해결하기 위해 사용됩니다.

 

동적 계획법의 주요 특징

1. 중복된 계산 제거: 동일한 부분 문제를 여러 번 계산하지 않고, 한 번 계산한 값을 저장해두고 다시 사용합니다.

2. 부분 문제: 큰 문제를 해결하기 위해서는 작은 문제들의 해결이 필요합니다.

3. 최적 부분 구조: 전체 문제의 최적 해결은 부분 문제의 최적 해결을 바탕으로 합니다.

4. 메모리 사용: DP는 계산한 값을 저장하는 테이블(보통 배열이나 리스트)을 사용합니다.

 

동적 계획법의 두 가지 기본 접근 방식

1. 탑다운 방식 (Top-down): 재귀 호출을 이용하여 문제를 풀고, 이미 계산한 값을 메모이제이션 기법을 통해 저장하여 중복 계산을 방지합니다.

2. 바텀업 방식 (Bottom-up): 작은 문제부터 차례대로 해결해 나가며 최종적으로 큰 문제를 해결합니다. 일반적으로 반복문을 사용합니다.

 

예시 문제: 피보나치 수열

피보나치 수열을 구하는 문제는 동적 계획법의 전형적인 예시입니다. 피보나치 수는 이전 두 수의 합으로 정의됩니다. 예를 들어, `fib(n) = fib(n-1) + fib(n-2)`입니다.

 

1. 탑다운 방식 (메모이제이션)

public class Fibonacci {

    // 메모이제이션을 위한 배열
    static int[] memo;
    
    public static int fib(int n) {
        // 이미 계산된 값이 있으면 그 값을 반환
        if (memo[n] != -1) {
            return memo[n];
        }

        // 피보나치 계산
        if (n <= 1) {
            memo[n] = n;
        } else {
            memo[n] = fib(n - 1) + fib(n - 2);
        }

        return memo[n];
    }

    public static void main(String[] args) {
        int n = 10; // 구하고자 하는 피보나치 수

        memo = new int[n + 1]; // 배열 크기 지정

        // 배열 초기화 (값이 계산되지 않았음을 표시하기 위해 -1로 초기화)
        for (int i = 0; i <= n; i++) {
            memo[i] = -1;
        }

        System.out.println(fib(n)); // 55 출력
    }
}

 

2. 바텀업 방식 (반복문)

public class Fibonacci {

    public static int fib(int n) {
        // 0과 1의 피보나치 값은 0과 1
        if (n == 0) return 0;
        if (n == 1) return 1;

        // 피보나치 수를 저장할 변수들
        int a = 0, b = 1, c = 0;

        // 2부터 n까지 반복하면서 피보나치 계산
        for (int i = 2; i <= n; i++) {
            c = a + b;
            a = b;
            b = c;
        }

        return c;
    }

    public static void main(String[] args) {
        int n = 10; // 구하고자 하는 피보나치 수

        System.out.println(fib(n)); // 55 출력
    }
}

 

동적 계획법의 효율성

- 시간 복잡도: 반복문이나 메모이제이션을 사용함으로써 시간 복잡도를 줄일 수 있습니다. 예를 들어, 피보나치 수열의 경우 단순 재귀로는 지수 시간 복잡도가 걸리지만, 동적 계획법을 사용하면 선형 시간 복잡도 O(n)으로 해결할 수 있습니다.

- 공간 복잡도: DP에서는 테이블을 사용하므로 공간을 어느 정도 차지합니다. 그러나 일부 문제에서는 공간 최적화를 통해 1차원 배열만으로도 해결할 수 있습니다.

 

DP 문제 해결 전략

1. 문제를 더 작은 부분 문제로 나눈다.

2. 부분 문제를 해결한 후 그 결과를 저장한다.

3. 중복 계산을 피하기 위해 저장된 값을 재사용한다.

 

동적 계획법은 특히 최적화 문제, 경로 문제, 조합 문제 등에서 효과적으로 사용됩니다.

반응형

'Dev > Algorithm' 카테고리의 다른 글

Bellman-Ford  (0) 2025.01.17
Dijkstra  (0) 2025.01.17
에라토스테네스의 체  (2) 2025.01.14
List  (0) 2024.12.31
Set  (0) 2024.12.31