https://www.acmicpc.net/problemset?sort=ac_desc&algo=25
동적 계획법이라고 불리며 탑다운과 보텀업 2가지 방식을 가지고 있다.(dynamic: 프로그램이 실행되는 도중에)
메모리 공간을 약간 더 사용하여 연산 속도를 비약적으로 증가시킬 수 있다는 특징을 가지고 있다.
다음 조건을 만족할 때 사용할 수 있다.
즉, 큰 문제를 작게 나누고, 같은 문제라면 한 번씩만 풀어 문제를 효율적으로 해결하는 알고리즘 기법.
dp의 가장 대표적인 예시로
a1 = 1, a2 = 1 외의 n번째 항: an = an-1 + an-2의 성질을 가지고 있다.
프로그래밍에서는 이러한 수열을 **배열(c, c++, java)**이나 **리스트(python)**로 표현할 수 있다.
두 가지 모두 ‘연속된 많은 데이터’를 처리한다는 점은 동일하다.
점화식은 재귀 함수를 사용해서 구현할 수 있다.
#피보나치 함수를 재귀함수로 표현
def fibo(x):
if x == 1 or x == 2:
return 1
return fibo(x-1) + fibo(x-2)
print(fibo(4))
하지만 다음과 같은 방식은 중복 함수가 호출되는 형식으로 빅 오 표기법으로 O(2^N), 지수 시간의 복잡도를 가진다.
<aside> 💡 메모이제이션(Memoization) 기법
다이나믹 프로그래밍을 구현하는 방법 중 한 종류로, 한 번 구한 결과를 메모리 공간에 메모해두고 같은 식을 다시 호출하면 메모한 결과를 그대로 가져오는 기법을 의미한다.
메모이제이션은 값을 저장하는 방법이므로 캐싱(Caching)이라고 한다.
실제로 구현하려면 한 번 구한 정보를 리스트에 저장하면 된다.
dp를 재귀적으로 수행하다가 같은 정보가 필요할 때는 이미 구한 정답을 그대로 리스트에서 가져오면 된다.
</aside>
메모이제이션 기법을 사용해 피보나치 수열 구현. 다음과 같은 방식은 O(N)의 시간 복잡도를 가진다.
#한 번 계산된 결과를 메모이제이션하기 위한 리스트 초기화
d = [0] * 100
#피보나치 함수를 재귀함수로 구현(탑다운 방식)
def fibo(x):
if x == 1 or x == 2:
return 1
# 이미 계산한 적 있는 문제라면 그대로 반환
if d[x] != 0:
return d[x]
# 계산하지 않은 경우
d[x] = fibo(x-1) + fibo(x-2)
return d[x]
print(fibo(99))