큰 문제를 작은 문제로 나누어 푸는 문제
(Dynamic(동적)이라는 이름의 의미는 딱히 없다고 함)
메모리를 적절히 사용하여 수행 시간 효율적을 비약적으로 향상 시킨다.
Divide and Conquer(분할 정복)과의 차이?
작은 문제의 반복이
일어나지 않는가 -> 분할 정복
일어나는가(답이 바뀌지 않음을 이용) -> DP
이미 계산된 결과(작은 문제)는 별도의 메모리 영역에 저장하고, 다시 사용한다.
결과 저장용 리스트는 DP 테이블이라고 부른다.
(계산된 결과를 담아 놓기만 하고 다시 활용하지 않을 지도..)
동일한 작은 문제를 반복적으로 해결해야 하는 경우이다.
큰 문제를 작은 문제로 나눌 수 있으며, 작은 문제의 답을 모아서 큰 문제를 해결할 수 있다.
// 계산된 결과를 저장하기 위한 DP 테이블 초기화
int d_T[100] = {0, };
int fibo_T(int n){
if (n <= 2)
return 1;
if (d_T[n] == 0){ // 연산 값이 있는지 없는지 검사 후 없으면 새로 연산
d_T[n] = fibo_T(n-1) + fibo_T(n-2);
}
return d_T[n]; // 있으면 바로 반환
}
// 계산된 결과를 저장하기 위한 DP 테이블 초기화
int d_B[100] = {0, };
int fibo_B(int n){
//첫 번째 피보나치 수와 두 번째 피보나치 수는 1
d_B[1] = 1;
d_B[2] = 1;
//피보나치 함수 반복문으로 구현 (보텀업 DP)
for (int i=3; i<=n; i++){
d_B[i] = d_B[i-1] + d_B[i-2];
}
return d_B[n];
}
DP는 큰 문제를 작은 문제들로 분할하여 해결한다.
이 때 작은 문제들의 값은 항상 같기 때문에 이를 저장해서 필요할 때마다 가져다 씀으로써 효율을 높인다.