Binary Search
Binary Search¶
풀이¶
JavaScript
const solution = (
requiredGold,
requiredSilver,
nearByGolds,
nearBySilvers,
nearByweights,
nearByTime
) => {
// 이분탐색의 범위: 최대 걸리는 시간
// 편도 최대시간 t = 10e5 -> 왕복 시 t = 10e5 * 2
// 한번에 1kg 씩 옮긴다 가정할 경우 금, 은을 모두 옮기는데 걸리는 총 시간
// t = (10e5 * 2) * (2 * 10e9)
let time = 10e5 * 4 * 10e9;
let start = 0;
let end = 10e5 * 4 * 10e9;
while (start <= end) {
let mid = Math.floor((start + end) / 2);
let goldCarry = 0;
let silverCarry = 0;
let allCarry = 0;
for (let i = 0; i < nearByGolds.length; i++) {
const goldReserves = nearByGolds[i]; // i국 금 (kg gold/city)
const silverReserves = nearBySilvers[i]; // i국 은 (kg silver/city)
const allowableWeight = nearByweights[i]; // i국에서 한번에 옮길 수 있는 최대 양 (kg/city)
const oneWayTime = nearByTime[i]; // i국에서 한번 옮길 때 걸리는 편도 시간 (hr/city)
// 도시 → 목적지 경로 횟수
const totalDeliveryCount = Math.ceil(Math.floor(mid / oneWayTime) / 2);
// 해당 도시가 최대로 옮길 수 있는 광물의 양 (kg): 전달 횟수 * 한번에 옮길 수 있는 양
const totalMineralConveyCapacity = totalDeliveryCount * allowableWeight;
// 금만 캤을 때 캘 수 있는 양
goldCarry += Math.min(totalMineralConveyCapacity, goldReserves);
// 은만 캤을 때 캘 수 있는 양
silverCarry += Math.min(totalMineralConveyCapacity, silverReserves);
// 최대로 옮길 수 있는 광물의 무게
allCarry += Math.min(
totalMineralConveyCapacity,
silverReserves + goldReserves
);
}
// 시간(mid)안에 가능한 경우
if (
requiredGold <= goldCarry &&
requiredSilver <= silverCarry &&
requiredGold + requiredSilver <= allCarry
) {
end = mid - 1;
time = Math.min(time, mid);
} else {
// 이 시간안에 해결 불가한 경우
start = mid + 1;
}
}
return time;
};
먼저 이 문제를 결정문제로 환원해보자.
시간 \(T\) 가 주어졌을 때, \(T\) 라는 시간 안에 트럭을 최대한 활용시켜 금과 은을 각각 \(a, b\) 만큼 운반할 수 있는지 판별하는 문제로 바꾸어 접근하면 된다.
그렇다면 해당 결정 문제는 다음과 같이 풀 수 있다.
- 제한 시간 안에 금을 최우선적으로 운반했을 때 운반할 수 있는 금의 양과 은의 양을 각각 \(G_{max}, S_{min}\) 정의 (금 우선 탐색)
- 제한 시간 안에 은을 최우선적으로 운반했을 때 운반할 수 있는 금의 양과 은의 양을 각각 \(G_{min}, S_{max}\) 정의 (은 우선 탐색)
- \(G_{max} + S_{min}\) = \(G_{min}, S_{max}\)
- 만약 다음과 같은 조건을 만족할 경우 주어진 시간 \(T\) 안에 a 만큼 금과 b 만큼 은을 운반할 수 있다.
- \(a \leq G_{max}\)
- \(b \leq S_{max}\)
- \(a + b \leq G_{max} + S_{min} = G_{min} + S_{max}\)
특정시간 \(T\) 에서
-
goldCarry= 특정시간 \(T\) 동안 얻을 수 있는 최대 골드 수 (\(Gmax\)) -
silverCarry= 특정시간 \(T\) 동안 얻을 수 있는 최대 실버 수 (\(Smax\)) -
allCarry= 특정시간 \(T\) 동안 골드와 실버를 한번에 얻을 수 있는 최대 수 (\(Gmin + Smax\))
이 세가지 값을 가지고 \(a + b <= Gmax + Smin = Gmin + Smax\) 이조건을 만족한다면 현재 t시간은 a, b를 운반할 수 있다를 결정할 수 있게된다.
참고 문서
마지막 업데이트 : 2025년 4월 23일
작성일 : 2023년 1월 29일
작성일 : 2023년 1월 29일
