Greedy

뚝딱이·2022년 7월 9일
0

[ 알고리즘 ]

목록 보기
1/3

그리디 알고리즘이란,

그리디 알고리즘은 탐욕법으로도 단순하지만, 강력한 문제 해결 방법이다.

탐욕적이라는 말은 현재 상황에서 지금 당장 좋은 것만 고르는 방법을 의미한다.
그리디 알고리즘을 이용하면, 매 순간 가장 좋아 보이는 것을 선택하며 현재의 선택이 나중에 미칠 영향에 대해서는 고려하지 않는다.

그리디 알고리즘은 사전에 외우고 있지 않아도 풀 수 있을 가능성이 높은 문제 유형이라는 특징이 있다.
하지만 다익스트라 알고리즘 같은 특이 케이스를 제외하고는 단순 암기를 통해 모든 문제를 대처하기 어렵다.

코딩 테스트에서 출제 되는 그리디 알고리즘 유형의 문제는 창의력, 즉 문제를 풀기 위한 최소한의 아이디어를 떠올릴 수 있는 능력을 요구한다.


대표적인 예시, 거스름돈

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

이 문제의 핵심은 가장 큰 화폐 단위부터 돈을 거슬러 주는 것이다.

N원을 거슬러줘야 한다고 했을 때, 먼저 500원을 거슬러줄 수 있는 만큼 거슬러준다. 그 다음으로 큰 100원을 거슬러 줄 수 있는 만큼 거슬러준다. 다음엔 50원을, 그리고 10원을 거슬러주면 최소 개수의 동전을 거슬러 줄 수 있다.

만약 거슬러 줘야할 돈, N이 1370원이라고 가정하자.

  1. 500원을 거슬러 줄 수 있는 만큼 거슬러준다.
    그렇다면, 1370에서 500원을 나눈 몫 만큼 줄 수 있을 것이다.
    1370 // 500 = 2로 500원짜리 동전 2개를 거슬러줄 수 있고,
    따라서 남은 돈은 나눈 나머지로 1370 % 500 = 370이 된다.

  2. 100원을 거슬러 준다. (남은 돈 = 370)
    동일한 방법으로 계산한다.
    370 // 100 = 3으로 100원짜리 동전 3개를 거슬러 줄 수 있고,
    따라서 남은 돈은 370 % 100 = 70이 된다.

  3. 50원, 남은 돈 = 70
    70 // 50 = 1로 50원짜리 동전 1개를 거슬러 줄 수 있고,
    따라서 남은 돈은 70 % 50 = 20이 된다.

  4. 10원, 남은 돈 = 20
    20 // 10 = 2로 10원짜리 동전 2개를 거슬러 줄 수 있고,
    따라서 남은 돈은 20 % 10 = 0이 되어 거스름돈을 다 거슬러 주었다.

따라서 거슬러주는 동전의 최소 개수는 8개 이다.

거슬러 줄 수 있는 돈은 나눈 몫이고, 남은 돈은 나머지가 된다는게 중요하다.
위의 1,2,3,4를 바탕으로 코드를 작성해보자

N = 1370
count = 0 # 동전의 개수

coin_types = [500, 100, 50, 10]

for coin in coin_types:
    count += N // coin
    N %= coin

print(count)

그리디 알고리즘의 정당성

그리디 알고리즘을 모든 알고리즘 문제에 적용할 수는 없다. 대부분의 문제가 그리디 알고리즘을 이용했을 때 '최적의 해'를 찾을 수 없을 가능성이 다분하기 때문이다.

하지만 위의 거스름돈 문제와 같이 탐욕적으로 문제에 접근했을 때 정확한 답을 찾을 수 있다는 보장이 있을 때는 매우 효과적이고 직관적이다.

위이 거스름돈 문제가 그리디 알고리즘을 해결할 수 있었던 이유는 가지고 있는 동전 중에서 큰 단위가 항상 작은 단위의 배수이므로 작은 단위의 동전들을 종합해 다른 해가 나올 수 없기 때문이다.

대부분의 그리디 알고리즘 문제에서는 문제 풀이를 위한 최소한의 아이디어를 떠올리고 이것이 정당한지 검토할 수 있어야 답을 도출할 수 있다.

profile
백엔드 개발자 지망생

0개의 댓글