일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- binary search
- greedy
- 2512
- 14921
- 백준
- Lower bound
- 1495
- EntityGraph
- 11501
- 이진 탐색
- 19598
- 무한페이징
- Blue/Green
- join제거
- 3187
- NCP
- 12738
- Promtail
- Java
- DP
- Upper bound
- slice개념
- no offset
- 로그
- 그리디
- 20115
- 이분 탐색
- 13975
- dto projection
- 모니터링
- Today
- Total
멘지의 기록장
[백준] 2512 : 예산 (JAVA) 본문
난이도
🥈 2
링크
https://www.acmicpc.net/problem/2512
2512번: 예산
첫째 줄에는 지방의 수를 의미하는 정수 N이 주어진다. N은 3 이상 10,000 이하이다. 다음 줄에는 각 지방의 예산요청을 표현하는 N개의 정수가 빈칸을 사이에 두고 주어진다. 이 값들은 모두 1 이상
www.acmicpc.net
문제
풀이과정
해당 문제도 이분탐색을 사용해서 푸는 문제이다.
이분탐색에 대해서는 아래 글에서 작성해두었으니 참고하면 좋을거 같다!
(풀이 설명도 아래의 글을 참고하면 될 것 같다.)
https://amepistheo.tistory.com/4
[백준] 2110 : 공유기 설치 (JAVA)
난이도 🥇 4 링크 https://www.acmicpc.net/problem/2110 2110번: 공유기 설치 첫째 줄에 집의 개수 N (2 ≤ N ≤ 200,000)과 공유기의 개수 C (2 ≤ C ≤ N)이 하나 이상의 빈 칸을 사이에 두고 주어진다. 둘째 줄부
amepistheo.tistory.com
정해진 총액 이하에서 가능한 한 최대의 총 예산(by 정수 상한액)을 출력하는 문제였기 때문에
이번에도 Upper Bound를 사용하면 되는 문제였다.
1) 최소 예산이 1이었기 때문에 left = 1로 설정
2) 최대 예산은 입력값의 최댓값인 right = money[N-1]로 설정
3) for문을 돌며 정수 상한액에 따른 총 예산 계산
4) 최종적으로 계산된 총 예산을 확인
계산된 총 예산과 주어진 총 예산을 비교하여
- 계산된 총 예산 > 주어진 총 예산
: 정수 상한액이 크게 잡혀있음 → 정수상한액 줄임 - 계산된 총 예산 < 주어진 총 예산
: 정수 상한액이 작게 잡혀있음 → 정수상한액 늘림 - 계산된 총 예산 = 주어진 총 예산
: 만족하는 정수상한액들 중 최댓값를 모름! → 정수상한액 늘림
➡️ 이 부분이 위 링크에 있는 문제와의 차이점인데
계산된 총 예산이 넘칠 때! 정수상한액을 줄여줘야 되고,
계산된 총 예산이 작거나 같을 때! 정수상한액을 늘려줘야하기 때문에
if문의 조건이 다르다는 걸 잘 알아둬야 한다!
Upper Bound (원하는 값 k를 초과한 값이 처음 나오는 위치를 찾는 과정')를 사용하여
위의 문제에서는 '가능한 한 최대의 총 예산'이 되도록하는 예산들 중 최댓값을 구해야하고,
left가 가장 마지막에 바뀐 값 (while문을 빠져나가는 조건이 left > right이기 때문)이므로 left - 1을 출력하면 된다.
🚨 이분탐색을 하기 전에 꼭! 정렬하는거 잊지 말기..
전체 코드
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
int N = Integer.parseInt(br.readLine());
int[] money = new int[N];
st = new StringTokenizer(br.readLine());
for (int i = 0; i < N; i++) {
money[i] = Integer.parseInt(st.nextToken());
}
Arrays.sort(money);
int M = Integer.parseInt(br.readLine());
int left = 1;
int right = money[N-1];
while (left <= right) {
int mid = (left + right) / 2;
int count = 0;
for (int i = 0; i < N; i++) {
if (money[i] < mid) {
count += money[i];
}
else {
count += mid;
}
}
if (count > M) {
right = mid - 1;
}
else {
left = mid + 1;
}
}
System.out.println(left - 1);
}
}
결과
'BOJ' 카테고리의 다른 글
[백준] 1449 : 수리공 항승 (JAVA) (0) | 2024.01.07 |
---|---|
[백준] 9252 : LCS 2 (JAVA) (1) | 2024.01.06 |
[백준] 2110 : 공유기 설치 (JAVA) (1) | 2024.01.02 |
[백준] 12738 : 가장 긴 증가하는 부분 수열 3 (JAVA) (1) | 2024.01.01 |
[백준] 11053 : 가장 긴 증가하는 부분 수열 (JAVA) (1) | 2023.12.31 |