본 게시글은 [링크] 해당 강의를 정리한 글입니다.
🔽 해당 조건을 만족할 때 (효율적으로)사용할 수 있다.
1
최적 부분 구조 (Oprimal Substructure)
2
중복되는 부분 문제 (Overlapping Subproblem)
1
재귀만 사용한 code ➡️ 계산의 중복 실행
public static int recur(int num) {
if ( num <= 2) return 1;
return recur(num - 1) + recur(num - 2);
}
2
동적 계획법으로 구현 했을 때의 함수 호출
// 바텀업 동적계획법으로 구현
public static long dinamicFibo(int n) {
long [] table = new long [n + 1];
table[0] = 0;
table[1] = 1;
for (int i = 2; i <= n; i++) {
table[i] = table[i-1] + table[i-2];
}
return table[n];
}
// 탑다운 동적계획법으로 구현
public static long dp(int n, long [] memo) {
if (n <= 1) {
return n;
} else if (memo[n] != 0) {
return memo[n];
} else {
return memo[n] = dp( n -1, memo) + dp(n -2, memo);
}
}
3
코드 실행 시 , 각 방법의 속도 비교
n = 50;
1. 재귀
실행시간 : 74.403초
2. DP (바텀업)
실행시간 : 0.0초
3. DP (탑다운)
실행시간 : 0.0초
⬛ 탑-다운 (하향식)
* 메모이제이션 (Memoization)
: 한 번 계산한 결과를 메모리 공간에 메모하는 기법
⬛ 보텀-업 (상향식)
공통점
차이점
1
그리디, 구현, 완전 탐색 등의 아이디어로 문제를 해결할 수 있는지 검토한다.
2
아이디어가 없다면 DP로 풀것을 고려한다.
3
재귀함수로 비효율적인 완전 탐색 프로그램을 작성한다. 탑다운(하향식)
4
작은문제에서 구한 답이 큰 문제에서 그대로 사용될 수 있으면, 코드를 개선하는 방법을 쓴다.
➡️ 익숙하지 않으면 어렵다. 많이 풀어봐야한다.