"이 글은 골든래빗 코딩 테스트 합격자 되기 파이썬 편 16장의 써머리입니다."
문제 해결 과정에서 결정 순간마다 눈 앞에 보이는 최선을 선택, 그 선택 번복 X
⇒ 그리디 알고리즘은 지역 최적해를 추구한다
* 부분적으로 최적해를 구한다고 할 수 있어도 전체적으로 최선의 해를 구했는지는 불확실
그리디 알고리즘으로 거스름돈 내어주기
상황) 손님에게 8원을 거슬러 줘야 하는데 동전 종류가 5, 4, 1원만 있음, 이때 동전 개수를 가장 적게 만들기 위해 그리디 알고리즘 활용
그리디 알고리즘이 최적해를 보장하려면?
그리디 알고리즘은 특정한 상황에서 최적해를 보장, 이를 잘 활용하면 문제를 해결 가능
그리디 알고리즘을 사용하는 대표적인 트리 형태의 자료구조
신장 트리(Spanning Tree)란?
모든 정점이 간선으로 연결되어 있고 간선 개수가 정점 개수보다 하나 적은 그래프
최소 신장 트리(Minimum Spanning Tree, MST)란?
신장 트리 중 간선의 가중치 합이 최소인 트리
경우에 따라 최소 신장 트리는 하나가 아닐 수도 있음
eg. 항공기의 운항 경로 최적화할 때 활용, 네트워크 분야에서 많이 활용
최소 신장 트리를 구하는 그리디 알고리즘
프림 알고리즘(Prim’s Algorithm)으로 최소 신장 트리 구하기
로버트 프림이 만든 알고리즘
크루스칼 알고리즘으로 최소 신장 트리 구하기
모든 간선을 가중치 기준으로 오름차순 정렬한다는 점 이외의 나머지 규칙은 프림 알고리즘과 동일
배낭에 담을 수 있는 최대 무게가 존재, 무게와 가치가 다른 짐들이 있을 때, 잘 조합해서 배낭의 무게를 초과하지 않으면서 담은 가치를 최대로 하는 문제
배낭 문제의 목표 - 최대한 배낭에 높은 가치의 짐을 넣는다
짐을 쪼갤 수 있는 부분 배낭 문제(Fractional Knapsack Problem)
부분 배낭 문제를 해결하려면 무게당 가치가 높은 짐을 최대한 많이 넣는 그리디 알고리즘 사용
짐을 쪼갤 수 없는 0/1 배낭 문제(0/1 Knapsack Problem)
이 문제는 짐을 쪼갤 수 없어서 지금 선택한 짐이 다음 짐 선택에 영향을 줌
그리디 알고리즘 적용 시 최적의 해 구할 수 없음(동적 계획법으로 접근 필요)
0/1 배낭 문제는 그리디 알고리즘으로 근사해를 구할 수 있다고 함
문제 80) 거스름돈 주기
거스름돈 amount가 있을 때 화폐 단위 [1, 10, 50, 100]을 최소한으로 사용한 화폐 리스트를 반환
def solution(amount):
lists = [100, 50, 10, 1]
changes = []
for c in lists:
while amount >= c:
changes.append(c)
amount -= c
return changes
assert solution(123) == [100, 10, 10, 1, 1, 1]
assert solution(350) == [100, 100, 100, 50]
문제 84) 귤 고르기
from collections import Counter
def solution(k, tangerine):
cnt = Counter(tangerine)
res, tot = 0, 0
lists = sorted(cnt.values(), reverse=True)
for count in lists:
tot += count
res += 1
if tot >= k:
break
return res
assert solution( 6, [1, 3, 2, 5, 4, 5, 2, 3]) == 3
assert solution( 4, [1, 3, 2, 5, 4, 5, 2, 3]) == 2
assert solution( 2, [1, 1, 1, 1, 2, 2, 2, 3]) == 1