DP (동적 계획법)
하나의 큰 문제를 여러 개의 작은 문제로 나누어서 그 결과를 저장하고
그 결과를 이용하여 다시 큰 문제를 해결할 때 사용하는 것
DP가 적용되기 위해선
1. 겹치는 부분이 존재해야한다.
문제를 작은 문제로 나누고 그 결과값을 저장한다. 저장한 값을 재활용하여 전체의 답을 구할 수 있을 때 사용한다.
즉, 겹치는 부분이 존재하지 않는다면 결과값을 저장해도 쓸모가 없기 때문에 dp를 사용할 수 없다.
2. 최적 부분 구조
작은 부분 문제에서 구한 최적의 답으로 합쳐진 큰 문제의 최적의 답을 구할 수 있어야한다.
문제의 최적 해결 방법이 부분 문제의 최적 해결 방법으로 구성된 문제 구조를 말한다.
DP 적용 방법
DP는 점화식의 연속이다. 점화식을 진행하는 방식에는 2가지가 있다.
1. Top-Down 방법
: 위에서 아래로 접근하는 방법으로, 큰 문제에서 부분 문제로 쪼개가면서 문제를 풀어가는 방식 => 재귀 사용
int fiboData[100] = {0,};
int fibo(int n)
{
if (n<=2)
return 1;
if (fiboData[n]==0)
fiboData[n] = fibo(n-1) + fibo(n-2);
return fiboData[n];
}
n을 구하기 위해 n-1식을 호출하고 계속해서 작은 값들로 쪼개지는 방식이다.
위 코드에서는 최근 값을 저장해두고 그 값을 이용하여 계속해서 계산하는 메모이제이션을 사용하여 진행되었다.
fibo[n] = fibo(n-1) + fibo(n-2) , fibo(n-1)과 fibo(n-2) 호출됨, fibo(n-1) = fibo(n-2) + fibo(n-3) .... 이런식으로 점점 쪼개짐
fibo(n)을 구하기 위해선 fibo(n-1)와 fibo(n-2)의 값을 알아야한다.
또한 fibo(n)의 값을 중복계산하지 않기 위해서 fiboDate[] 배열에 계산값을 저장해둔다. <메모이제이션>
2. Bottom-Up 방법
: 아래서 위로 접근하는 방법으로, 부분 문제에서부터 문제를 해결하여 점차 큰 문제를 풀어가는 방식 => 반복문 사용
int fibo(int n)
{
fibodata[0] = 0;
fiboData[1] = 1;
for (int i=2; i<=n; i++)
fiboData[i] = fiboData[i - 1] + fiboData[i - 2];
return fiboData[n];
}
0에서 부터 시작하여 각 값을 저장하고 n에 도달하는 방식
즉 fibo[0], fibo[1] 구하고 이를 이용해 fibo[2] 구함 , 1,2로 fibo[3] 구함 ... n까지 계산
+참고하면 좋을 문제
https://hihajin.tistory.com/34#toc14
백준 1003번 : 피보나치 함수 | 메모이제이션, dp 알고리즘 [C++]
https://www.acmicpc.net/problem/1003 1003번: 피보나치 함수 각 테스트 케이스마다 0이 출력되는 횟수와 1이 출력되는 횟수를 공백으로 구분해서 출력한다. www.acmicpc.net 주어진 피보나치 함수에서 n이 0일때
hihajin.tistory.com
#메모이제이션 #dp 알고리즘 #피보나치
+ 추천 문제
'💡알고리즘' 카테고리의 다른 글
DFS : 깊이 우선 탐색 (Depth First Search) | Python 구현 (0) | 2024.03.09 |
---|---|
[알고리즘] 그리디(Greedy: 탐욕) 알고리즘 (0) | 2023.05.20 |
[자료구조] 트리 (Tree) (0) | 2023.05.12 |
[자료구조] Priority Queue (우선순위 큐) (0) | 2023.05.07 |
[자료구조] Set (0) | 2023.05.07 |