알고리즘

[Java] 알고리즘 Day8

Jaemin0604 2024. 7. 8. 00:35

다이나믹 프로그래밍

DP(Dynamic Programming)

  • 중복되는 연산을 줄이는 방식
  • 문제를 작은 하위 문제로 나누어 해결한 결과를 저장해 두었다가, 동일한 하위 문제가 다시 나타날 때 이를 재사용하는 방식

다이나믹 프로그래밍의 기본 원리

  1. 중복된 하위 문제:
    • 문제를 작은 하위 문제로 나누었을 때, 동일한 하위 문제가 여러 번 반복해서 나타나는 경우.
    • 예를 들어, 피보나치 수열 계산에서는 F(n) = F(n-1) + F(n-2)와 같은 형태로, 동일한 계산이 반복된다.
  2. 최적 부분 구조:
    • 문제의 최적해가 하위 문제들의 최적해로 구성될 수 있는 경우.
    • 예를 들어, 최단 경로 문제에서는 전체 경로의 최적해가 부분 경로의 최적해들로 구성된다.

다이나믹 프로그래밍의 두 가지 접근법

1. 탑다운(Top-Down) 접근법 (메모이제이션)

  • 재귀 호출을 통해 문제를 하위 문제로 나누고, 이미 계산된 하위 문제의 결과를 저장하여 중복 계산을 방지
  • 일반적으로 재귀와 메모이제이션(결과 저장) 기법을 사용
// 메모이제이션을 이용한 피보나치 수열
public class Fibonacci {
    private static Map<Integer, Long> memo = new HashMap<>();

    public static long fib(int n) {
        if (n <= 1) return n;
        if (memo.containsKey(n)) return memo.get(n);

        long result = fib(n - 1) + fib(n - 2);
        memo.put(n, result);
        return result;
    }

    public static void main(String[] args) {
        System.out.println(fib(50)); // 예시 출력
    }
}

 

2. 바텀업(Bottom-Up) 접근법 (반복문)

// 바텀업을 이용한 피보나치 수열
public class Fibonacci {
    public static long fib(int n) {
        if (n <= 1) return n;

        long[] dp = new long[n + 1];
        dp[0] = 0;
        dp[1] = 1;

        for (int i = 2; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }

        return dp[n];
    }

    public static void main(String[] args) {
        System.out.println(fib(50)); // 예시 출력
    }
}

 

다이나믹 프로그래밍의 예시 문제

  1. 피보나치 수열
    • 문제: F(n) = F(n-1) + F(n-2), F(0) = 0, F(1) = 1
    • 중복된 하위 문제와 최적 부분 구조를 가지며, DP로 해결 가능
  2. 최단 경로 문제
    • 예를 들어, 그래프에서 두 점 사이의 최단 경로를 찾는 문제 (다익스트라 알고리즘, 벨만-포드 알고리즘)
  3. 배낭 문제(Knapsack Problem)
    • 문제: 제한된 무게 내에서 가치가 최대가 되도록 물건을 선택하는 문제
    • DP를 통해 하위 문제를 해결하며 최적해를 찾음
  4. 최장 공통 부분 수열(Longest Common Subsequence)
    • 문제: 두 문자열에서 공통된 부분 문자열 중 가장 긴 것을 찾는 문제
    • DP를 통해 부분 문제를 해결하며 전체 문제를 해결

다이나믹 프로그래밍의 장점과 단점

  • 장점
    • 중복 계산을 피할 수 있어 시간 복잡도를 크게 줄일 수 있음
    • 다양한 최적화 문제를 효율적으로 해결할 수 있음
  • 단점
    • 문제에 따라 추가적인 메모리 사용이 필요할 수 있음
    • 문제를 DP로 변환하는 과정이 복잡할 수 있음