큰 문제를 작게 나누고, 같은 문제라면 한 번씩만 풀어 문제를 효율적으로 해결하는 알고리즘 기법으로, 동적 계획법으로 불리기도 한다.

DP 알고리즘을 적용하기 위해서는 다음 2가지 조건을 만족해야 한다.
Overlapping SubproblemOptimal Substructure
주어진 문제가 여러 개의 부분 문제(subproblem)로 쪼개질 수 있는 것을 말한다.
대표적인 예로 피보나치 수열이 있다. 피보나치 수열은 첫째 항과 둘째 항이 1이며, 그 뒤에 모든 항이 바로 앞 두 항의 합인 수열을 말한다.
N번째 피보나치 수를 구할 때, (N - 2)번째 피보나치 수 구하기 + (N - 1)번째 피보나치 수 구하기로 작은 문제로 나눌 수 있다.
새로운 부분 문제의 정답을 다른 부분 문제의 정답으로부터 구할 수 있는 것을 말한다.
앞에서 언급한 피보나치 수열을 구할 때, 8번째 피보나치 수를 구하면서 구했던 4번째 피보나치 수와 9번째 피보나치 수를 구하면서 구했던 4번째 피보나치 수는 항상 같다.
즉 매번 4번째 피보나치 수를 구하지 않고, 전에 구했던 값을 기억해서 사용할 수 있다.
다이나믹 프로그래밍의 접근 방법에는
Top-Down과Bottom-Up가 있다.
Top-Down(탑-다운)이라고 한다.메모이제이션은 탑다운 방식에 국한되어 사용되는 표현이다. Bottom-Up 방식으로 구현하는 것이 좋다. sys 라이브러리에 포함되어 있는 setrecursionlimit() 함수를 호출하여 재귀 제한을 완화할 수 있다.d = [0] * 100
def fibo(x):
print('f(' + str(x) + ')', end=' ')
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]
fibo(6)
Bottom-Up(보텀업) 방식이라고 한다.DP 테이블이라고 부른다.d = [0] * 100
d[1] = d[2] = 1
n = 99
for i in range(3, n + 1):
d[i] = d[i - 1] + d[i - 2]
print(d[n])
큰 문제를 작은 문제로 나눈다는 측면에서 분할 정복 알고리즘과 비슷하게 느껴지지만 다음과 같은 차이점이 존재한다.
이것이 코딩테스트다 with 파이썬 책
galid1님의 블로그
gillog님의 벨로그
polynomeer님의 벨로그
kimlog님 블로그
kyun2da님 블로그