[백준 11399] ATM 문제 - 그리디 알고리즘
📖 그리디 알고리즘이란?
정의: 매 순간 가장 좋아 보이는 선택을 하는 알고리즘
특징: 한 번 선택하면 되돌리지 않음 (No 후회!)
핵심: "지금 당장 최선 = 나중에도 최선"이라고 가정
일상 예시
동전으로 거스름돈 주기: 1000원을 거슬러 줄 때
× 잘못된 선택: 1원짜리부터 → 1000개 필요
○ 그리디 선택: 500원부터 → 500원 2개 = 총 2개
그리디를 쓸 수 있는 조건
- 탐욕적 선택 속성: 지역 최적해가 전역 최적해의 일부
- 최적 부분 구조: 작은 문제들의 최적해로 전체 최적해 구성 가능
📌 문제 요약
ATM에서 N명이 줄을 설 때, 모든 사람의 대기시간 합을 최소화하는 문제. 각 사람마다 인출하는데 걸리는 시간이 다르고, 줄 서는 순서에 따라 총 대기시간이 달라진다.
입력: N (사람 수), P₁ P₂ ... Pₙ (각 사람의 인출 시간)
출력: 모든 사람의 대기시간 합의 최솟값
출처: https://www.acmicpc.net/problem/11399
💡 문제 접근
- 이 문제가 그리디인 이유: 앞사람의 선택이 뒤의 모든 사람에게 영향을 줌
- 핵심 관찰: 앞사람의 인출시간이 뒤의 모든 사람 대기시간에 누적됨
- 그리디 전략: 매 순간 가장 짧은 시간의 사람을 선택
- 증명: 임의의 두 사람 A(a분), B(b분)에서 a < b라면, A→B가 B→A보다 항상 효율적
🔍 그리디 선택 과정
주어진 시간: [3, 1, 4, 3, 2]
1단계: 가장 짧은 시간 선택 → 1분 (전체에 1분씩 5명 = 5분 영향)
2단계: 다음 짧은 시간 선택 → 2분 (전체에 2분씩 4명 = 8분 영향)
3단계: 다음 짧은 시간 선택 → 3분 (전체에 3분씩 3명 = 9분 영향)
...
이렇게 매번 최선의 선택을 하면 전체 최적해를 얻을 수 있다!
📝 풀이 코드 (JavaScript)
const fs = require('fs');
const input = fs.readFileSync(0, 'utf8').trim().split('\n');
const n = +input[0];
const times = input[1].split(' ').map(Number);
// 그리디 전략: 매번 가장 짧은 시간 선택 (정렬)
times.sort((a, b) => a - b);
let answer = 0;
let sum = 0;
for (let time of times) {
sum += time; // 현재 사람의 대기시간
answer += sum; // 전체에 누적
}
console.log(answer);
🔎 풀이 해설
- times.sort(): 그리디 전략을 위한 정렬 (가장 짧은 것부터)
- 반복문에서 각 사람의 대기시간 계산:
- sum += time: 현재 사람이 기다리는 시간
- answer += sum: 전체 대기시간에 누적
- 예시: [1,2,3,3,4] → 대기시간: 1+3+6+9+13 = 32분
💭 내 생각
- "그리디가 항상 최적일까?" 의문이 들었는데, 수학적으로 증명 가능하다는 게 신기함!
- 일상에서도 그리디 사고를 많이 쓰고 있었구나... (지하철에서 가까운 문 찾기 등)
- 핵심은 "이 선택이 나중에 영향을 주는가?"를 분석하는 것
📚 배운 점
- 그리디 vs DP: 그리디는 선택을 되돌리지 않음, DP는 모든 경우를 고려
- 그리디 적용 조건: 지역 최적해가 전역 최적해가 되는 문제에서만 사용 가능
- 증명의 중요성: 그리디가 최적임을 수학적으로 증명할 수 있어야 함
- 정렬의 활용: 많은 그리디 문제에서 정렬이 핵심 전략
'알고리즘 풀이' 카테고리의 다른 글
백준 2606번 바이러스 (JavaScript 풀이) (0) | 2025.09.09 |
---|---|
백준 1463번 1로 만들기 (JavaScript 풀이) (0) | 2025.09.06 |
백준 1003번 피보나치 함수 (JavaScript 풀이) (0) | 2025.09.05 |
백준 2164번 카드2 (JavaScript 풀이) (8) | 2025.08.23 |