문제링크
https://www.acmicpc.net/problem/5585
문제
타로는 자주 JOI잡화점에서 물건을 산다. JOI잡화점에는 잔돈으로 500엔, 100엔, 50엔, 10엔, 5엔, 1엔이 충분히 있고, 언제나 거스름돈 개수가 가장 적게 잔돈을 준다. 타로가 JOI잡화점에서 물건을 사고 카운터에서 1000엔 지폐를 한장 냈을 때, 받을 잔돈에 포함된 잔돈의 개수를 구하는 프로그램을 작성하시오.
입력
입력은 한줄로 이루어져있고, 타로가 지불할 돈(1 이상 1000미만의 정수) 1개가 쓰여져있다.
출력
제출할 출력 파일은 1행으로만 되어 있다. 잔돈에 포함된 매수를 출력하시오.
해석
그리디 알고리즘의 대표적인 문제이다.
욕심쟁이 알고리즘이라고도 불리는 그리디 알고리즘(Greedy Algorithm)이란 지금 단계에서 가장 최선의 선택을 하고 이 선택이 전체적으로도 최선이길 바라는 알고리즘이다.
조금 더 간단하게 예를 들어 이해해보도록 하자.
현재 먹을 수 있는 음식은 라면이다. 하지만 5분만 기다리면 소고기 스테이크가 나온다. 라면을 더 좋아하는 사람이 아니라면 5분을 기다려 소고기 스테이크를 먹을 것이다. 하지만 그리디 알고리즘은 현재에 최선을 다하기 때문에 기다리지 않고 라면을 먹어치운다. (그래서 욕심쟁이 알고리즘이라고 불리운다.)
문제에 적용해보자.
잔돈을 500, 100, 50, 10, 5, 1엔짜리를 갖고 있고 잔돈을 적게 주기 위해서는 큰 잔돈부터 거슬러줘야 하는 값에서 뺴준다. 예를 들어 650원을 거슬러줘야 한다면
600 - 500 - 100 - 50 = 0 이 되는 것이다.
코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#include <iostream>
using namespace std;
// 거스름돈 배열
int mon[] = { 500,100,50,10,5,1 };
int main() {
int money, num = 0, count = 0;
cin >> money;
money = 1000 - money;
while (money != 0) {
while (money < mon[num]) {
num++;
}
money = money - mon[num];
count++;
}
cout << count;
}
|
cs |
Memo
그리디 알고리즘의 대표적인 문제인 만큼 그리디 알고리즘에 대해 공부할 수 있었던 좋은 예였다.