아래 내용은 Greedy(탐욕법)의 핵심 개념을 먼저 정리한 뒤, A4greedy 패키지에 있는 실습 코드(최소 동전 개수)를 통해 “정렬 기준 → 매 선택의 규칙 → Greedy가 성립하는 조건(언제 맞고 언제 틀리는지)”를 한 흐름으로 정리한 글이다.
Greedy는 “매 순간 가장 좋아 보이는 선택”을 반복해서 답을 만들어내는 방식이다. 즉, 각 단계에서의 지역 최적(local optimum)을 선택해 전역 최적(global optimum)을 노린다
다만 모든 문제에서 정답을 보장하진 않고, “이 문제는 Greedy 규칙이 항상 맞다”는 성질이 성립할 때만 안전하게 사용할 수 있다.
Greedy 문제는 전형적인 DP처럼 “항상 같은 형태의 점화식”이 있는 게 아니라, 문제에 맞는 규칙(rule) 을 찾아야 한다.
규칙이 맞는지 확인할 때는 보통 다음을 점검한다.
최소 동전 문제는 “현재 남은 금액에서 가장 큰 동전을 최대한 많이 쓰는 선택”이 전체 동전 개수도 줄여준다는 규칙이 성립할 때 Greedy로 풀 수 있다.
단, 모든 동전 체계에서 이 규칙이 성립하는 건 아니고(예: 특정 동전 구성에서는 반례 존재), 문제에서 주어진 동전 체계가 Greedy를 허용하는 형태인지가 중요하다.
int[] arr = {10, 5, 1, 20};
Arrays.sort(arr);
정렬을 해두면 뒤에서부터 순회하면서 큰 동전 → 작은 동전 순으로 처리할 수 있다.
Greedy는 “매 순간의 선택 규칙”이 핵심이라서, 이 문제에서는 “가장 큰 동전부터 최대한 사용”이 그 규칙이 된다.
int b = target / a; // 몫
total += b;
target -= b * a;
현재 금액(target)에서 동전 a를 몇 개 쓸 수 있는지 몫으로 구하고, 그 개수를 누적(total)한 뒤 남은 금액으로 target을 갱신한다.
이 흐름 자체가 “현재 시점 최선(가장 큰 동전 사용)”을 선택하는 Greedy의 전형적인 구현이다.
Greedy는 빠르고 구현이 간단하지만, “항상 맞는 규칙인지” 검증 없이 적용하면 오답이 나올 수 있다.
그래서 코딩테스트에서는 보통 아래 방식으로 안전성을 확보한다.