DP
- 정의
크고 복잡한 문제를 여러 개의 부분 문제로 나누어 푸는 방법
=> 부분 문제들 풀고 값 저장, 해당 문제 다시 만날 때 재연산하지 않고 저장해둔 값 불러옴
- 조건
1. 부분 반복 문제
부분 문제가 여러 번 재사용되는 경우 (=진행했던 연산이 반복되는 경우)
2. 최적 부분 구조
부분 문제에서 구한 최적의 값을 이용해(합산해) 큰 문제의 최적의 값을 구함
- 특징
메모이제이션(Memoization)
: 메모리에 부분 문제 값 저장해나감 → 연산 반복될 시 저장해둔 값 사용
=> 주로 배열 사용해 값 저장
- 구현 방법 (예시 - 피보나치 수열)
가장 작은 문제(base case) & 점화식 구한 후, Bottom-up 또는 Top-down 방식으로 구현하기
1. Bottom-up 방식
: 반복문을 통해 부분 문제의 값 저장해나가며 큰 문제의 값을 구하는 방식
public static int bottomUp(int n){
//base case
memo[0]=0;
memo[1]=1;
for (int i=2;i<=n;i++){
memo[i]=memo[i-1]+memo[i-2]; //점화식 : 앞의 두 숫자 합산 반복
}
return memo[n];
}
2. Top-down 방식
: 재귀 함수를 이용해 큰 문제에서 작은 문제를 호출해가며 값을 도출하는 방식
public static int topDown(int n){
if (n<=2){ //base case
return 1;
}
if (n>0){ //이미 메모이제이션 배열에 저장된 값이 있을 때
return memo[n]; //저장된 값 불러옴
}
return memo[n]=memo[n-1]+memo[n-2]; //점화식
}
참고 :
'Programming > 알고리즘' 카테고리의 다른 글
[자료구조] 트리, 그래프 (0) | 2023.05.11 |
---|---|
DFS, BFS (0) | 2023.05.04 |
[자료구조] 선형 구조 - 스택(Stack), 큐(Queue), 덱(Deque) (0) | 2023.03.20 |
[백준/자바] 브루트포스 7568번 - 덩치 (0) | 2023.03.10 |
[백준/자바] 브루트포스 2798번 - 블랙잭 (0) | 2023.03.04 |