개념 / 적용 조건 / 실전 예제 / DP와 비교
그리디 알고리즘(Greedy Algorithm)은
현재 상황에서 가장 좋아 보이는 선택을 반복적으로 수행하여
전체 문제의 최적해를 찾는 알고리즘이다.
❗ '지금 당장' 최적인 선택이
'전체적으로도' 최적인 결과를 보장할 때만 정답이 된다.
항상 정답이 되려면 아래 두 가지 조건을 만족해야 한다.
✔ 둘 다 만족할 때 → 그리디로 풀 수 있음
500원, 100원, 50원, 10원짜리 동전이 있을 때
거스름돈을 가장 적은 수의 동전으로 바꿔라
coins = [500, 100, 50, 10]
n = 1260
count = 0
for coin in coins:
count += n // coin
n %= coin
print(count) # 6 (500x2 + 100x2 + 50x1 + 10x1)
✔️ 큰 동전부터 사용하는 것이 항상 최적이라는 보장이 있음 → 그리디 가능
❗ 동전 종류가 400원, 300원, 100원 이런 식이면? → 그리디 불가능 (DP 필요)
N개의 회의가 있고, 각 회의의 시작/끝 시간이 주어짐
최대 몇 개의 회의를 겹치지 않고 배정할 수 있을까?
meetings = [(1, 4), (3, 5), (0, 6), (5, 7), (3, 9), (5, 9), (6, 10)]
meetings.sort(key=lambda x: (x[1], x[0])) # 종료 시간 기준 정렬
end_time = 0
count = 0
for start, end in meetings:
if start >= end_time:
count += 1
end_time = end
print(count)
✔️ 매 순간 가장 빨리 끝나는 회의를 선택 → 그리디 전략
✔️ 이건 우선순위 큐 (heapq)를 활용한 Greedy + 자료구조 문제다!
항목 | 그리디 | DP |
---|---|---|
선택 기준 | 지금 가장 좋아 보이는 것 | 모든 경우를 고려하며 누적 |
계산 방식 | 한 방향으로만 진행 | 중복 계산을 막고 누적 |
메모리 | 적음 | 테이블/메모 필요 |
정답 보장 | 구조적으로 보장될 때만 | 항상 보장됨 (올바른 설계 시) |
예시 | 동전 거스름돈, 회의실 배정 | 피보나치, 배낭 문제, 1로 만들기 |
→ 그렇다면 그리디 알고리즘을 먼저 시도해볼 만하다.
그리디처럼 당장 최선의 선택을 반복하는 알고리즘들이 꽤 많지만,
전부 그리디 알고리즘으로 분류되진 않는다.
알고리즘 | 실제 분류 | 설명 |
---|---|---|
거스름돈 문제 (단, 배수 관계가 성립할 때) | ✅ 그리디 | 큰 단위 동전부터 선택 → 항상 최적 |
활동 선택 문제 | ✅ 그리디 | 끝나는 시간 빠른 회의를 먼저 고르면 전체 최적 |
크루스칼 알고리즘 (MST) | ✅ 그리디 | 가장 가중치 작은 간선을 먼저 선택 |
허프만 코딩 | ✅ 그리디 | 가장 빈도 낮은 노드부터 병합 |
결정 트리 학습 | ✅ 그리디 기반 | 각 단계에서 가장 좋은 기준으로 분할 (탐욕적 학습) |
다익스트라 알고리즘 | ❗ 그리디 + 우선순위 큐 | 가장 가까운 정점부터 방문하지만, 그래프 탐색 알고리즘 |
프림 알고리즘 (MST) | ❗ 그리디 + 그래프 구조 | 연결된 정점 중 가장 짧은 간선을 선택 (우선순위 큐 활용) |
탐욕적인 선택을 하더라도, 그게 전체 최적해를 보장하는 구조여야 "진짜 그리디"라고 할 수 있다.