반응형
🚀 1. 그리디 알고리즘이란?
**그리디 알고리즘(Greedy Algorithm)**은 매 순간 가장 좋아 보이는 선택(최적해)을 하면서 전체 문제를 해결하는 알고리즘이에요.
💡 쉽게 이해하기
- 🍕 피자를 한 조각씩 먹을 때, 가장 맛있는 부분부터 먹는 것!
- 💰 잔돈 거슬러 줄 때, 가장 큰 화폐 단위부터 사용하는 것!
- 📆 회의 일정을 잡을 때, 가장 빨리 끝나는 회의부터 선택하는 것!
📌 그리디 알고리즘의 핵심 원칙
- 탐욕적 선택 속성(Greedy Choice Property): 각 단계에서 최선의 선택을 해도 최적의 해를 얻을 수 있어야 해요.
- 최적 부분 구조(Optimal Substructure): 부분 문제의 최적해가 전체 문제의 최적해를 구성해야 해요.
➡ 즉, 매 순간 최적의 선택을 하면서 문제를 해결하는 방식이에요!
🚀 2. 그리디 알고리즘을 사용할 수 있는 경우
📌 그리디 알고리즘이 올바르게 동작하려면?
- 현재 선택이 앞으로의 선택에 영향을 주지 않아야 해요. (즉, 최적 부분 구조가 있어야 해요!)
- 각 단계에서의 최선의 선택이 전체 문제에서의 최적해를 보장해야 해요. (즉, 탐욕적 선택 속성이 있어야 해요!)
📌 그리디 알고리즘이 자주 사용되는 문제 유형
문제 유형 예제
최소 동전 거스름돈 | 가장 큰 화폐 단위부터 거슬러 주기 |
회의실 배정 | 가장 빨리 끝나는 회의부터 선택 |
배낭 문제 (Fractional Knapsack) | 가장 비싼 물건부터 담기 |
Huffman Coding | 데이터 압축 알고리즘 |
➡ 그리디 알고리즘이 항상 정답을 보장하는 것은 아니지만, 적용 가능한 문제에서는 매우 효율적이에요!
🚀 3. 그리디 알고리즘 구현 예제
✅ 1) 최소 동전 거스름돈 문제
💡 문제:
거스름돈 n원을 줄 때, 가장 적은 개수의 동전을 사용하세요.
📌 그리디 알고리즘 해결 방법
- 가장 큰 단위의 동전부터 거슬러 준다.
- 남은 금액을 다시 거슬러 준다.
💡 Python 코드 구현
def min_coins(n, coins):
count = 0
for coin in coins:
count += n // coin # 해당 동전으로 거슬러 줄 수 있는 개수
n %= coin # 남은 금액 갱신
return count
coins = [500, 100, 50, 10] # 가장 큰 단위부터 정렬
print(min_coins(1260, coins)) # 출력: 6
➡ 500원 2개, 100원 2개, 50원 1개, 10원 1개로 총 6개의 동전이 필요해요!
✅ 2) 회의실 배정 문제
💡 문제:
여러 개의 회의 일정이 주어졌을 때, 가장 많은 회의를 할 수 있는 방법을 찾아보세요.
📌 그리디 알고리즘 해결 방법
- 회의를 종료 시간이 빠른 순서로 정렬한다.
- 가장 빨리 끝나는 회의를 선택하고, 다음 회의를 이어서 선택한다.
💡 Python 코드 구현
def max_meetings(meetings):
meetings.sort(key=lambda x: x[1]) # 종료 시간을 기준으로 정렬
count = 0
last_end = 0
for start, end in meetings:
if start >= last_end: # 이전 회의가 끝난 후 시작할 수 있는 경우
count += 1
last_end = end
return count
meetings = [(1, 4), (3, 5), (0, 6), (5, 7), (3, 8), (5, 9), (6, 10)]
print(max_meetings(meetings)) # 출력: 4
➡ 그리디하게 종료 시간이 빠른 회의부터 선택하면, 최대한 많은 회의를 진행할 수 있어요!
✅ 3) 배낭 문제 (Fractional Knapsack)
💡 문제:
무게 제한이 있는 배낭에 최대한 가치를 높이도록 물건을 담아보세요. (단, 물건을 쪼갤 수 있음)
📌 그리디 알고리즘 해결 방법
- 가치 대비 무게 비율이 높은 물건부터 담는다.
- 배낭이 가득 찰 때까지 반복한다.
💡 Python 코드 구현
def fractional_knapsack(items, capacity):
items.sort(key=lambda x: x[1] / x[0], reverse=True) # 가치/무게 비율 기준 정렬
total_value = 0
for weight, value in items:
if capacity >= weight:
total_value += value
capacity -= weight
else:
total_value += value * (capacity / weight)
break
return total_value
items = [(10, 60), (20, 100), (30, 120)] # (무게, 가치)
capacity = 50
print(fractional_knapsack(items, capacity)) # 출력: 240.0
➡ 가장 가치 있는 물건부터 채우면, 최대 가치를 얻을 수 있어요!
🚀 4. 그리디 알고리즘의 한계
📌 그리디 알고리즘이 항상 정답을 보장하지 않는 이유
- 탐욕적 선택이 전체 최적해가 아닐 수 있어요. (예: 0-1 배낭 문제)
- 백트래킹이나 동적 프로그래밍(DP)이 필요한 경우가 있어요.
- 모든 문제에서 적용 가능한 것은 아니에요.
💡 그리디가 실패하는 예제: 0-1 배낭 문제
- 물건을 쪼갤 수 없는 경우, 그리디 알고리즘이 최적해를 보장하지 않아요.
- 이 경우 **동적 프로그래밍(DP)**을 사용해야 해요.
➡ 그리디 알고리즘이 적용 가능한 문제인지 먼저 확인하는 것이 중요해요!
✅ 마무리 정리
- 그리디 알고리즘은 매 순간 최적의 선택을 하면서 문제를 해결하는 방법이에요.
- 탐욕적 선택 속성과 최적 부분 구조가 만족될 때 효과적으로 사용할 수 있어요.
- 자주 출제되는 유형: 최소 동전 거스름돈, 회의실 배정, 배낭 문제 등
- 하지만 모든 문제에서 최적해를 보장하는 것은 아니므로 주의해야 해요!
반응형
'IT > algorithm' 카테고리의 다른 글
[Python] 알고리즘 개념20 - 이진 탐색(Binary Search) (1) | 2025.02.28 |
---|---|
[Python] 알고리즘 개념19 - 정렬 알고리즘 (퀵 정렬, 병합 정렬, 힙 정렬) (0) | 2025.02.27 |
[Python] 알고리즘 개념18 - 분할 정복(Divide and Conquer) (1) | 2025.02.27 |
[Python] 알고리즘 개념17 - 완전 탐색(Brute Force) (0) | 2025.02.27 |
[Python] 알고리즘 개념15 퀴즈 - 세그먼트 트리 (0) | 2025.02.24 |
[Python] 알고리즘 개념15 - 세그먼트 트리(Segment Tree) (0) | 2025.02.24 |
[Python] 알고리즘 개념14 퀴즈 - 유니온 파인드 (0) | 2025.02.24 |
[Python] 알고리즘 개념14 - 유니온 파인드(Disjoint Set) (0) | 2025.02.24 |
댓글