-
원래 문제를 풀 수 있을 정도의 작은 크기의 부분 문제들로 분할해 각각 해결한 후, 부분 문제의 해답을 잘 모아 원래 문제의 해답을 얻는 방법
- 크기가 작아질 뿐 문제 자체는 변하지 않기 때문에, 분할은 재귀적인 분할이 된다.
- 재귀적인 분할이므로 분할정복 방법의 알고리즘 수행시간 T(n)은 점화식으로 표현되는 것이 일반적이다.
-
예1: n개의 수 중에서 최대 값 구하기 A: [3, 0, -5, 7, 2, -4, 6 9]
def find_max1(A):
if len(A) == 1: return A[0]
else: return max(A[0], find_max1(A[1:]))
T(n)=T(n−1)+c=O(n)
def find_max2(A):
if len(A) < 1: return -infinity
elif len(A) == 1: return A[0]
else: return max(A[:len(A)//2], A[len(A)//2:])
T(n)=2T(2n)+c=O(n)
2k=n -> k=log2n,T(1)=c
T(n)=2T(2n)+c
T(n)=22T(22n)+2c+c
⋮
T(n)=2kT(2kn)+c(1+2+...+ 2^(k-1) )
T(n)=c(1+2+...+2k)
=2−11∗(2(k+1)−1)=c(2n−1)
=O(n)
그림으로 풀기

T(n)=c(1+2+...+2k)
=2−11∗(2(k+1)−1)=c(2n−1)
=O(n)
- 예2: an을 계산하기(n을 양의 정수로 가정)
def power1(a, n):
if n == 1:
return a
return a * power1(a, n-1)
수행시간 점화식: T(n) = T(n-1) + c = O(n)
def power2(a, n):
if n == 0: return 1
if n%2 == 1:
return power2(a, n//2)*power(a, n//2)*a
else:
return power2(a, n//2)*power(a, n//2)
수행시간 점화식: T(n) = 2T(n/2) + c = O(n)
power(a, n//2)를 이미 구했는데 여러번 호출하는 것은 비효율적!
변수 p에 저장해놓고 재사용하자!
def power3(a, n):
if n == 0: return 1
p = power2(a, n//2)
if n%2 == 1:
return p * p * a
else:
return p * p
수행시간 점화식: T(n) = T(n/2) + c = O(log n)
2k=n -> k=log2n
T(n)=T(2n)+c
=T(22n)+c+c
⋮
=T(2kn)+k∗c
c(k+1)=O(logn)