[알고리즘 기초] 그리디

딱지의겨울

·

2021. 5. 25. 17:19

현재 상황에서 지금 당장 좋은 것만 고르는 방법.
  • 매 순간 가장 좋아 보이는 것을 선택하고 현재의 선택이 나중에 미칠 영향에 대해서는 고려하지 않음. 
  • 코테에서 그리디 알고리즘 문제 유형은 사전에 외우고 있지 않아도 풀 수 있는 가능성이 높음. (다익스트라 알고리즘 제외)
  • 따라서 많은 유형을 접해보고 문제를 풀어보며 훈련을 해야 함. 
  • 보통 창의력(문제를 풀기위한 최소한의 아이디어를 떠올릴 수 있는 능력)을 요구.
  • 단순히 현재 상황에서 가장 좋아 보이는 것만을 선택해도 문제를 풀 수 있는지를 파악할 수 있어야 함. 
  • 기준에 따라 좋은 것을 선택하는 알고리즘 이므로 문제에서 '가장 큰 순서대로', '가장 작은 순서대로'와 같은 기준을 알게 모르게 제시해 줌. 대체로 이 기준은 정렬 알고리즘을 사용했을 때 만족시킬 수 있으므로 그리디 알고리즘 문제는 자주 정렬 알고리즘과 짝을 이뤄 출제됨. 

 

대표문제: 거스름돈

당신은 음식점의 계산을 도와주는 점원이다. 카운터에는 거스름돈으로 사용할 500원, 100원, 50원, 10원짜리 동전이 무한히 존재한다고 가정한다. 손님에게 거슬러 줘야 할 돈이 N원일 때 거슬러 줘야할 동전의 최소 개수를 구하라. 단, 거슬러 줘야할 돈 N은 항상 10의 배수이다. 

= 가장 큰 화폐 단위부터 돈을 거슬러 주는 것. 

n = int(input())
cnt = 0

# 큰 단위 화폐부터 차례로 확인
c_type = [500,100,50,10]

for coin in c_type:
  cnt += n // coin # python에서는 몫 구할 때 // 사용
  n %= coin

print(cnt)
  • 화폐의 종류가 K개라고 할때 시간 복잡도는 O(K)
  • 이 코드는 거슬러줘야 하는 금액의 크기와는 무관하고 동전의 총 종류에만 영향을 받음.
  • 코테에서의 그리디 유형의 문제는 일반적으로 거스름돈 문제보다는 난이도가 높음. 하지만 문제에 접근하는 방법은 유사하므로 자주 소개되는 문제. 

 

그리디 알고리즘의 정당성

  • 대부분의 문제는 그리디 알고리즘을 이용했을 때 최적의 해를 찾을 수 없을 가능성이 다분함. 탐욕적으로 문제에 접근했을 때 정확한 답을 찾을 수 있다는 보장이 있을 때는 매우 효과적이고 직관적임.
  • 거스름돈 문제를 그리디 알고리즘으로 해결할 수 있는 이유는 가지고 있는 동전 중에서 큰 단위가 항상 작은 단위의 배수이므로 작은 단위의 동전들을 종합해 다른 해가 나올 수 없기 때문임. 큰 단위가 작은 단위의 배수 형태이므로 가장 큰 단위부터 작은 단위까지 차례로 거슬러주는 작업을 수행하면 된다는 아이디어는 정당함. 실제로 거스름돈 문제에서 단위가 서로 배수 형태가 아니라 무작위로 주어진 경우에는 그리디 알고리즘으로 해결할 수 없음. (이 때는 DP 알고리즘 사용)
  • 대부분의 그리디 알고리즘 문제에서는 이처럼 문제 풀이를 위한 최소한의 아이디어를 떠올리고 이것이 정당한지 검토할 수 있어야 답을 도출할 수 있음. 
  • 바로 문제 유형을 파악하기 어려우면 그리디 알고리즘을 의심하고, 찾을 수 없다면 DP나 그래프 알고리즘으로 풀 수 있는지 재차 고민해보자.

 

'알고리즘 > 그리디' 카테고리의 다른 글

[그리디] 1이 될 때까지  (0) 2021.05.27
[그리디] 숫자 카드 게임  (0) 2021.05.27
[그리디] 큰 수의 법칙  (0) 2021.05.25