1. 동적 계획법 (Dynamic Programming)이란?
- 큰 문제를 작은 문제로 나누어 푸는 문제를 일컫는 말
- 하나의 문제는 단 한번만 풀도록 하는 알고리즘
2. 분할 정복과 차이점
* 분할 정복
- 큰 문제를 해결하기 어려워 단지 작은 문제로 나누어 푸는 방법
- 작은 문제에서 반복이 일어나는 부분이 없음
* 동적 프로그래밍
- 작은 부분 문제들이 반복되는것을 이용해 풀어나감
3. Dynamic Programming 방법
- 모든 작은 문제들을 한번만 풀어야 한다.
- 푼 작은 문제의 정답을 어딘가에 메모해 놓음
- 다시 그보다 큰 문제를 풀어나갈 때 똑같은 작은 문제가 나타나면 앞서 메모한
작은 문제의 결과값을 이용
* 조건
- 작은 문제가 반복이 일어나는 경우
- 같은 문제는 구할 때마다 정답이 같음
=> 위의 조건을 만족하는 경우에만 동적프로그래밍을 사용할 수 있다.
4. Memoization
- 컴퓨터 프로그램이 동일한 계산을 반복해야 할 때, 이전에 계산한 값을 메모리에 저장함으로써
동일한 계산의 반복 수행을 제거하여 프로그램 실행 속도를 빠르게 하는 기술
ex) 피보나치 수열 - 1 , 1 , 2 , 3 , 5 , 8 , ... => f(n) = f(n-1) + f(n-2) (n>=2)
위와 같은 점화식을 갖기 때문에 재귀 함수를 통해 간단하게 구현할 수 있지만 n이 증가함에 따라
호출되는 함수의 수가 기하급수 적으로 증가하기 때문에 일정 수 이상의 순열을 구하기 어려움
* 동적 계획법의 조건 2가지 상기
1. 작은 문제들이 반복
2. 같은 문제는 구할때 마다 정답이 같음
=> 위 두가지 조건을 만족하기 때문에 동적 계획법 적용 가능
* 동적 계획법 Code (C++) - Top down
피보나치 수열은 수열이 1개만 늘어나도 계산 량은 2배가 늘어나기 때문에 50번째 피보나치 수열을 계산하는
연산량은 2의 50제곱으로 볼 수 있다.
대략 1,000,000,000,000,000개 이상의 계산을 처리 해야함. => DP 활용
한번 계산한 값을 배열에 저장하여 다시 써야할 상황이 오면 함수를 호출하지 않고 배열안에 있는 값을
그대로 사용하여 연산량을 줄일 수 있음. => Memoization
* 동적 계획법 Code (C++) - Bottom up
1. 직관적으로 풀 수 있는 작은 문제는 풀어놓음
2. 점화식을 이용하여 반복문을 돌림. 작은 문제에서 구한 해를 이용하여 큰 문제를 풀기 때문에
시간 복잡도를 줄일 수 있음
* Top-down vs Bottom-up
- Top-down방식에 Memoization을 활용했다는 가정하에 시간 복잡도는 같음
- 하지만 실제 걸리는 시간은 Top-down dp가 더 길다고 일반적으로 알려져 있음
- 재귀DP의 장접은 점화식 그대로 호출이 되기 때문에 형식/순서에 얽매이지 않음
- for문 DP의 장점은 시간이 적게 걸림
- 따라서 문제에 따라 둘 중 어느 방법을 활용할지 알아야함
* 요약
1. DP는 큰 문제를 작은 문제들로 분할하여 그것을 이용해 큰 문제를 해결하는 방법
2. 분할정복과 다른점은 DP의 경우 작은 부분 문제의 답이 항상 같음
3. 문제를 풀 때 시간복잡도를 고려하여 top-down과 bottom-up중 선택해야함
'자료구조 C++' 카테고리의 다른 글
그리디 알고리즘 (0) | 2021.03.05 |
---|---|
DFS와 BFS (0) | 2021.02.24 |
9. 우선 순위 큐 (Heap) (0) | 2021.02.07 |
8. 이진 탐색 트리 (binary search tree) (0) | 2021.02.03 |
7. 트리(tree) (0) | 2021.02.03 |