

공유기 설치를 먼저 풀고 나니 쉽게 풀린 문제이다. 전형적인 이분탐색 문제라는 것을 알 수 있다.
public static int budgetSum(int val) {
int sum = 0;
for (int i = 0; i < n; i++) {
sum += Math.min(arr[i], val);
}
return sum;
}
low와 high를 각각 low = 1, high = 요청 예산 중 최댓값 + 1로 지정 후 이분탐색을 시작한다. int low = 1;
int high = arr[n - 1] + 1;
while (low < high) {
int mid = (low + high) / 2;
if (budgetSum(mid) > m) {
// 예산 총합이 초과 → 상한액이 너무 큼 → 줄여야 함
high = mid;
} else {
// 예산 총합이 여유 있음 → 상한액을 더 키워볼 수 있음
low = mid + 1;
}
}
이분 탐색의 시간 복잡도:
예산의 총합을 계산하는 메서드:
총합계산 메서드는 매 이분탐색마다 수행됨.
총 시간복잡도:
package BOJ;
import java.io.*;
import java.util.*;
public class sol2512 {
static int n;
static int[] arr;
static int m;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
arr = new int[n];
StringTokenizer st = new StringTokenizer(br.readLine());
for (int i = 0; i < n; i++) {
arr[i] = Integer.parseInt(st.nextToken());
}
Arrays.sort(arr);
m = Integer.parseInt(br.readLine());
int low = 1;
int high = arr[n - 1] + 1;
while (low < high) {
int mid = (low + high) / 2;
if (budgetSum(mid) > m) {
high = mid;
} else {
low = mid + 1;
}
}
System.out.println(low - 1);
}
public static int budgetSum(int val) {
int sum = 0;
for (int i = 0; i < n; i++) {
sum += Math.min(arr[i], val);
}
return sum;
}
}