다이나믹 프로그래밍은 주어진 문제를 하위 문제(subproblem)로 나누어 푸는 방법입니다. 중복된 계산을 피하기 위해 작은 하위 문제의 결과를 저장하고 재활용합니다. 문제가 최적 부분 구조(optimal substructure)와 중복되는 하위 문제(overlapping subproblems)를 갖고 있을 때 적용 가능합니다.

// 알고리즘 - 다이나믹 프로그래밍
public class Main {
// 피보나치 수열 (일반 풀이 - O(n^2))
// 계산했던 부분도 다시 계산
public static int fib(int n) {
if(n <= 1){
return n;
}else{
return fib(n - 1) + fib(n - 2);
}
}
// 피보나치 수열(DP 풀이 - 타뷸레이션 - O(n))
public static int fibDP(int n) {
int[] dp = new int[n < 2 ? 2 : 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];
}
// 피보나치 수열 (DP 풀이 - 메모이제이션 - O(n))
static int[] dp = new int[8];
public static int fibDP2(int n) {
if(n <= 2){
return 1;
}
if(dp[n] != 0){
return dp[n];
}
dp[n] = fibDP2(n - 1) + fibDP2(n - 2);
return dp[n];
}
public static void main(String[] args) {
System.out.println(fib(7));
System.out.println(fibDP(7));
System.out.println(fibDP2(7));
}
}