불러오는 중
적어도 미터 이상의 나무를 얻을 수 있는 가장 큰 정수 를 구하라.
를 0부터 까지 모두 시도해 보면 의 범위가 까지 갈 수 있어 시간 안에 못 푼다.
관찰: 가 커질수록 얻는 양이 단조롭게 줄어든다. 그러면 "이 로 이상을 얻을 수 있나?"라는 결정 함수가 단조롭다. 답에 이진 탐색을 걸자.
int can(long long H) {
long long total = 0;
for (int i = 0; i < N; i++) {
if (L[i] > H) total += L[i] - H;
if (total >= M) return 1; // 빨리 종료
}
return total >= M;
}
// 이진 탐색
long long lo = 0, hi = max_L;
long long ans = 0;
while (lo <= hi) {
long long mid = lo + (hi - lo) / 2;
if (can(mid)) { ans = mid; lo = mid + 1; }
else hi = mid - 1;
}
검사가 이고 이진 탐색이 이라 전체 .
입력 1
4 7
20 15 10 17
출력 1
15
설명: 위 그림처럼 이면 . 이면 이라 불가.
입력 2
5 20
4 42 40 26 46
출력 2
36
설명: 이면 . 이면 .
입력 3
1 1
1000000000
출력 3
999999999
설명: 이면 정확히 1만큼 얻을 수 있다.