이 문제는 뒤쪽(가장 먼 집)부터 처리하는 그리디 알고리즘을 활용해야겠다고 생각했다!
뒤쪽부터 처리하기
최대 거리 결정
index + 1) * 2한 번 이동에서 cap 만큼 처리
반복 처리
import java.util.*;
class Solution {
public long solution(int cap, int n, int[] deliveries, int[] pickups) {
long answer = 0;
int dIdx = n - 1; // deliveries의 마지막 인덱스 (가장 먼 집)
int pIdx = n - 1; // pickups의 마지막 인덱스 (가장 먼 집)
// 아직 배달 또는 수거할 집이 남아있는 동안 반복
while (dIdx >= 0 || pIdx >= 0) {
// 배달할 집 중 남은 건수가 0인 집은 건너뛰기
while (dIdx >= 0 && deliveries[dIdx] == 0) {
dIdx--;
}
// 수거할 집 중 남은 건수가 0인 집은 건너뛰기
while (pIdx >= 0 && pickups[pIdx] == 0) {
pIdx--;
}
// 배달과 수거가 모두 완료되었다면 종료
if (dIdx < 0 && pIdx < 0) {
break;
}
// 이번 회 이동할 최대 거리는 두 포인터 중 더 큰 값(인덱스)에 1을 더한 거리
int dist = Math.max(dIdx, pIdx) + 1;
answer += (long) dist * 2; // 왕복 이동 거리 누적
int deliverCap = cap; // 이번 회 배달 처리에 사용할 남은 용량
int pickupCap = cap; // 이번 회 수거 처리에 사용할 남은 용량
// 배달 처리: 가장 먼 집부터 cap 만큼 배달을 처리
while (dIdx >= 0 && deliverCap > 0) {
if (deliveries[dIdx] <= deliverCap) {
deliverCap -= deliveries[dIdx];
deliveries[dIdx] = 0;
dIdx--;
} else {
deliveries[dIdx] -= deliverCap;
deliverCap = 0;
}
}
// 수거 처리: 가장 먼 집부터 cap 만큼 수거를 처리
while (pIdx >= 0 && pickupCap > 0) {
if (pickups[pIdx] <= pickupCap) {
pickupCap -= pickups[pIdx];
pickups[pIdx] = 0;
pIdx--;
} else {
pickups[pIdx] -= pickupCap;
pickupCap = 0;
}
}
}
return answer;
}
}