코딩 테스트 대비를 하면서 느낀 진짜 어려운 파트 중 하나가 Greedy 라는 파트이다.
이 파트가 왜 어렵게 느껴졌을까?
대부분 코딩 테스트, 알고리즘 을 학습할때
print, a+b 등의 문제를 풀고 나서 처음으로 마주하는 문제가 아래와 같은 문제이다.
https://www.acmicpc.net/problem/5585
5585번: 거스름돈
타로는 자주 JOI잡화점에서 물건을 산다. JOI잡화점에는 잔돈으로 500엔, 100엔, 50엔, 10엔, 5엔, 1엔이 충분히 있고, 언제나 거스름돈 개수가 가장 적게 잔돈을 준다. 타로가 JOI잡화점에서 물건을 사
www.acmicpc.net

"쉬운데요?" 이건 쉽지.. 너무 직관적으로 방법이 떠오르고 그 방법이 맞기 때문이다.
그렇다면 이 문제는?
https://codeforces.com/problemset/problem/158/B
Problem - 158B - Codeforces
codeforces.com

1, 2, 3, 4명씩의 4개의 그룹이 각각 랜덤 갯수씩 있고 각 그룹의 인원들은 같은 택시에 타야한다.
또한 택시에 한번에 탑승가능한 최대 인원은 4명이고 모든 그룹이 택시에 타게 될때, 최소로 필요한 택시의 수를 구하는 것이다.
이제 바로 어떻게 풀어야 할 지 생각이 드나??
아니요...
놀랍게도 이 문제 역시 Greedy 알고리즘이다.
그렇다면 Greedy 알고리즘이란 무엇인가?
무엇이길래 언제는 쉽고 언제는 어렵게 느껴질까?
Greedy는 한국말로 탐욕법이라고 불린다.
그런데 나는 탐욕법이라는 워딩때문에 지금까지 해당 알고리즘에 대해 오해하고 있었던 것 같다.
돌이켜 생각해보니 그리디 알고리즘은
'이 방법으로 하면 맞겠는데?' 라는 생각에서 (like 거스름돈 문제)
'이 방법 외에는 될 수가 없어' 가 더 맞는 것 같다. (like Taxi 문제)
풀어 써본다면,
거스름돈 문제의 경우, '큰 수부터 나눠보지 뭐~' 가 아니라 '큰 수부터 나눠야 제일 작은 수의 동전 갯수가 나온다' 라는 것이고
Taxi 문제의 경우, '(2, 2), (1, 3) 이렇게 짝지어야 될 것 같은데?' 가 아닌 '(1, 3)으로 짝지을 수밖에 없는 문제네' 가 되는 것이다.
물론, 나도 이 글을 작성하는 건 답을 알고 나서의 이야기라
처음에 바로 Taxi 문제의 명쾌한 해결방법을 떠올리진 못했다..ㅎㅎ
Taxi 문제를 보면, 그럼 왜 (1, 3) 을 짝지어 줘야 할까?
우선 4명인 그룹은 바로 택시에 태우면 된다.
만약 (1, 3) 의 짝이 아니라 , (2, 1, 1)로 택시를 채운다 생각해보자
그렇다면, 3의 그룹이 탄 어떤 택시는 1자리가 비어있을 것이다. 어떤 택시는 여러대가 될 수도 있다.
이런 3만 타고 있는 택시가 여러대라면,
(2, 1, 1)에서 (1, 1)을 빼서 2개의 3만 탄 택시 빈자리에 채우면
다른 (2, 1, 1)에서 (2)를 앞의 (1, 1) 이 나간 자리에 채우면 되는 거잖아?
이 방법이 연쇄적으로 진행되면 저~~~~ 뒤쪽의 (2, 1, 1)들은
결국 앞으로 당겨져 비워진 택시가 될 것이고
이 말은 곧
(2, 1, 1)로 짝짓는다면 최소 택시 수를 만족 못시킨다는 의미이다.
따라서 1은 3과 짝지어줘야 한다.
이 풀이가 곧 Greedy 이다.
정답인 풀이의 논리가 아니라면 문제의 조건을 만족하지 못하게 되는 경우!
마치 (0 <= a < 7)이 정답이라면,
(a < 0 or a>=7)를 만족시키는 그 어떠한 값도 정답이 될 수 없는 것처럼 말이다!
이 논리가 다익스트라에서 최소비용을 구할 때의 노드 선택하는 과정에서도 진행되는데, 언제 한번 정리해야겠다 ㅎ
정리하자면,
정답인 풀이가 아니라는 것을 가정해보고
해당 풀이가 틀림이 주장되면 정답인 풀이가 맞다는 것이다.
물론 ㅎ 정답인 풀이를 바로 떠올리는 건 항상 어려운 것 같다ㅎ
그래도 문제의 접근 방법으로 잘 쓰면 좋은 판별 요건이 될 것 같다.
끘!
만일, 떠올린 그리디 알고리즘이 틀린 것 같다면, 아래 3방법을 시도해보자
1. 다른 알고리즘 생각해보기
2. 위의 과정을 이용해 그리디 증명해보기 -> 만약 내가 생각한 방법이 아닌데 되는 답이 나온다면, 내 방법이 틀린 것임
3. 반례를 찾으려 노력해보기
김성열 교수님 '알고리즘 연습' 수업을 듣고 이해한 내용을 정리한 내용입니다.
'알고리즘 공부' 카테고리의 다른 글
얕보면 안되는 a = b (0) | 2024.02.18 |
---|---|
중등수학으로 2차원 배열 방향 전환 이해하기 (3) | 2024.01.03 |