다이나믹 프로그래밍
: 큰 문제와 작은 문제를 나눠서 해결하는 기법
1. Overlapping Subproblem
- 큰 문제와 작은 문제를 같은 방법으로 풀 수 있다
- 문제를 작은 문제로 쪼갤 수 있다
2. Optimal Substructure
- 문제의 정답을 작은 문제의 정답에서 구할 수 있다
- 메모를 한다고 해서 "Memoization"
Tob-down
1. 문제를 풀어야한다
2. 문제를 작은 문제로 나눈다
3. 작은 문제를 푼다
4. 작은 문제를 풀었으니, 이제 문제를 푼다
# 재귀 함수로 구현
# 시간복잡도 : 채워야하는 칸의 수(memo 배열) X 1칸을 채우는 시간복잡도
Bottom-up
1. 문제를 크기가 작은 문제부터 차례대로 푼다
2. 문제의 크기를 조금씩 크게 만들면서 문제를 점점 푼다
3. 작은 문제를 풀면서 왔기 때문에, 큰 문제는 항상 풀 수 있다
4. 그러다보면, 언젠간 풀어야하는 문제를 풀 수 있다
# 반복문을 이용해 구현
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #include <iostream> using namespace std; int fibonacci(int n); int main(int argc, const char * argv[]) { int t; cin >> t; cout << fibonacci(t) << endl; } int d[100]; int fibonacci(int n){ if(n<=1){ return n; }else{ if(d[n]>0){ return d[n]; } d[n] = fibonacci(n-1) + fibonacci(n-2); return d[n]; } } | cs |
다이나믹 문제 풀이 전략
- 문제에서 구하려고 하는 답을 문장으로 나타낸다
- 예 : 피보나치 수를 구하는 문제
- N번째 피보나치 수
- 이제 그 문장에 나와있는 변수의 개수만큼 메모하는 배열을 만든다
- Top-down인 경우에는 재귀 호출의 인자 개수
- 문제를 작은 문제로 나누고, 수식을 이용해서 문제를 표현
'Algorithm > 알고리즘' 카테고리의 다른 글
[Algorithm] 진법 변환 알고리즘 (0) | 2019.02.09 |
---|---|
[Algorithm] 비트마스킹 (0) | 2019.01.06 |
[Algorithm] 탐색 알고리즘 (0) | 2018.11.25 |
[Algorithm] 완전탐색0 (0) | 2018.08.02 |
[Algorithm] 알고리즘과 입출력 (0) | 2018.07.30 |