동적 계획법은 최적화 문제를 연구하는 수학 이론에서 나왔다.
큰 의미에서 분할 정복과 같은 접근 방식을 가진다.
처음 주어진 문제를 더 작은 문제들로 나눈 뒤 각 조각의 답을 계산한다.
계산한 답들로부터 원래 문제를 계산한다.
동적 계획법에서 어떤 문제는 두개 이상의 문제를 푸는데 사용될 수 있다. 그래서 여러 번 사용되는 답을 한번 계산 후 재활용하여 속도를 향상시킨다.
캐시(cache) - 이미 계산한 값을 저장해 두는 메모리의 장소.
Overlapping subproblems - 두 번 이상 계산되는 부분 문제.
함수의 결과를 저장하는 장소를 마련해두고, 한번 계산한 값을 저장해뒀다가 재활용하는 최적화 기법이다.
전에 계산된 값은 저장되어 재활용되기 때문에, 모든 부분 문제가 한번 씩만 호출된다고 보장할 수 있어, 함수 호출 횟수가 엄청나게 감소한다.
함수의 반환값이 그 입력값만으로 결정되는지의 여부를 참조적 투명성(referential transparency)라고 한다.
입력이 고정되어 있을때, 그 결과가 항상 같은 함수들을 참조적 투명 함수라 하고, 메모제이션은 참조적 투명함수의 경우에만 적용가능하다.
동적 계획법은 가장 흔한 문제 유형 중 하나여서, 메모제이션을 굉장히 자주 구현한다.
한 가지 패턴을 가지고 구현하면, 작성하기도 버그 찾기도 쉬워진다.
각 입력에 대해 함수를 처음으로 호출할 때와 다음으로 호출 할 때 걸리는 시간이 다르기 때문에 분석하는 게 약간 까다롭다.
메모제이션을 사용하는 알고리즘의 시간 복잡도를 굉장히 간단하게 계산할 수 있는 방법.
(존재하는 부분 문제의 수) x (한 부분 문제를 풀 때 필요한 반복문의 수행횟수).
재귀호출을 이용하지 않고, 동적 계획법 알고리즘 구현이 가능하다.
해당 방법을 재귀 호출이 아닌 for문을 사용하여, 반복적 동적계획법을 구현하는 것이다.
재귀 호출을 통해 구현하는 것이 메모제이션을 통한 접근에 좀 더 직관적이다.
동적 계획법의 가장 일반적인 사용처는 최적화 문제의 해결이다.
최적환 문제란 여러 개의 가능한 답중 가장 좋은 답을 찾아내는 문제이다.
최적화 문제를 동적 계획법으로 푸는 것 또한, 완전 탐색에서 시작한다.
완전탐색으로 풀기 -> 완전 탐색에서 겹치는 부분을 부분 문제를 찾기 -> 메모제이션 적용.
프로그래밍 대회에서 배우는 알고리즘 문제 해결 전략 - 구종만