탐욕 알고리즘이라고도 하는 그리디 알고리즘은 문제를 해결할 때마다 그 순간에 최적이라고 생각되는 선택을 해나가는 방식으로 문제를 해결하는 방법이다. "탐욕스럽게" 각 단계에서 최선의 선택을 하여 최종적인 해답에 도달하는 것이다. 이 방식은 매 선택 시점에서 지역적으로 최적인 결정을 하기 때문에 각 단계에서의 최선의 선택이 전체적으로도 최선이라는 보장은 없다.
당신은 음식점의 계산을 도와주는 점원이다. 카운터에는 거스름돈으로 사용할 500원, 100원, 50원, 10원짜리 동전이 무한히 존재한다고 가정한다. 손님에게 거슬러 줘야 할 돈이 N원일 때 거슬로 줘야 할 동전의 최소 개수를 구하라. 단, 거슬러 줘야 할 돈 N은 10의 배수이다.
예를 들어 입력으로 주어진 N이 1,260이라면 다음과 같이 가장 큰 화폐 단위로부터 거슬러 주는 과정을 통해 1,260원을 모두 거슬러 줄 수 있다.
step 0 초기 단계 - 남은 돈: 1,260원
| 화폐 단위 | 500 | 100 | 50 | 10 |
|---|---|---|---|---|
| 손님이 받은 개수 | 0 | 0 | 0 | 0 |
step 1 남은 돈: 260원
| 화폐 단위 | 500 | 100 | 50 | 10 |
|---|---|---|---|---|
| 손님이 받은 개수 | 2 | 0 | 0 | 0 |
step 2 남은 돈: 60원
| 화폐 단위 | 500 | 100 | 50 | 10 |
|---|---|---|---|---|
| 손님이 받은 개수 | 2 | 2 | 0 | 0 |
step 3 남은 돈: 10원
| 화폐 단위 | 500 | 100 | 50 | 10 |
|---|---|---|---|---|
| 손님이 받은 개수 | 2 | 2 | 1 | 0 |
step 4 남은 돈: 0원
| 화폐 단위 | 500 | 100 | 50 | 10 |
|---|---|---|---|---|
| 손님이 받은 개수 | 2 | 2 | 1 | 1 |
따라서 N이 1,260일 때 손님이 받은 동전의 최소 개수는 6개이다.
n= 1260
count = 0
# 큰 단위의 화폐부터 차례대로 확인
coin_types = [500, 100, 50, 10]
for coin in coin_types:
# 해당 화폐로 거슬러 줄 수 있는 동전의 개수 세기
count += n // coin
n %= coin
print(count)
코드를 보면 화폐의 종류만큼 반복을 수행해야 한다. 따라서 화폐의 종류가 N개라고 할 때 시간 복잡도는 O(N)이다. 이 알고리즘의 시간 복잡도는 동전의 총 종류에만 영향을 받고, 거슬러 줘야 하는 금액의 크기와는 무관하다는 것을 알 수 있다.
그리디 알고리즘과 다이나믹 프로그래밍은 모두 최적화 문제를 해결하기 위한 알고리즘 기법이지만, 접근 방식과 적용하는 문제의 유형에서 차이를 보인다.
결론적으로, 그리디 알고리즘은 각 단계에서의 최선의 선택이 전체 문제 해결에 최선이라는 보장이 필요한 문제에 적합하고, 다이나믹 프로그래밍은 문제의 최적 부분 구조와 중복되는 하위 문제들을 효율적으로 해결할 수 있을 때 적합하다.
출처
이것이 취업을 위한 코딩 테스트다 with 파이썬