공부/알고리즘

DP(동적 계획법)

확두뇌 2023. 12. 17. 16:08

ex) 최대, 최소, 방법의 개수, 미래의 계산이 앞선 계산 결과에 영향을 받을 때

 

(1) 크고 복잡한 문제를 하위 문제로 나눈다.

(2) 하위 문제에 대한 답을 계산한다.

    - 중복 하위 문제

    - 계산 결과를 저장해서 중복된 문제에 사용

(3) 하위 문제에 대한 답으로 원래 문제에 대한 답을 계산한다.

 

상향식(bottom-up) 방법 - 반복문

public class DynamicProgrammingExample {

    // 다이나믹 프로그래밍을 활용한 피보나치 수열 계산
    public static int fibonacci(int n) {
        int[] dp = new int[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) {
        int n = 10; // 계산할 피보나치 수열의 인덱스
        int result = fibonacci(n);
        System.out.println("피보나치 수열의 " + n + "번째 값: " + result);
    }
}

 

하향식(Top-down) 방법 - 재귀, 메모리제이션

public class DynamicProgrammingMemoizationExample {

    // 메모리제이션을 활용한 피보나치 수열 계산
    public static int fibonacci(int n, int[] memo) {
        if (n <= 1) {
            return n;
        }

        // 이미 계산한 값이 있는지 확인하고 있다면 바로 반환
        if (memo[n] != 0) {
            return memo[n];
        }

        // 계산한 값을 저장하고 반환
        memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo);
        return memo[n];
    }

    public static void main(String[] args) {
        int n = 10; // 계산할 피보나치 수열의 인덱스
        int[] memo = new int[n + 1]; // 메모이제이션을 위한 배열

        int result = fibonacci(n, memo);
        System.out.println("피보나치 수열의 " + n + "번째 값: " + result);
    }
}