분할 정복(divide and conquer)이랑 동적 계획법(DP) 이 둘이 계속 헷갈립니다. 둘 다 큰 문제를 작은 문제로 쪼개서 푸는 거잖아요. 그럼 사실상 같은 거 아닌가 싶은데 왜 따로 이름 붙여서 구분하는 건지 모르겠어요.
피보나치로 예를 들면요.
// 그냥 재귀 (분할 정복 느낌)
def fib(n):
if n <= 1: return n
return fib(n - 1) + fib(n - 2)
// DP (메모이제이션)
def fib(n, memo={}):
if n <= 1: return n
if n in memo: return memo[n]
memo[n] = fib(n - 1, memo) + fib(n - 2, memo)
return memo[n]
이 두 개 보면 분할 정복은 쪼갠 문제들이 서로 안 겹치고 각각 딱 한 번씩만 푸는 거고(머지소트 같은), DP는 쪼갠 문제들이 서로 겹쳐서(fib(n-1)이랑 fib(n-2)가 둘 다 fib(n-3)을 부르잖아요) 같은 걸 여러 번 계산하게 되니까 저장해두고 재활용하는 거, 이렇게 이해하면 되는 건가요?
그러니까 핵심 차이가 "부분 문제가 겹치느냐(overlapping subproblems)"에 있는 게 맞나요? 겹치면 DP, 안 겹치면 분할 정복 이렇게 딱 나눠도 되는 건지, 아니면 제가 놓치고 있는 다른 기준이 또 있는지 궁금합니다.