2512번: 예산
첫째 줄에는 지방의 수를 의미하는 정수 N이 주어진다. N은 3 이상 10,000 이하이다. 다음 줄에는 각 지방의 예산요청을 표현하는 N개의 정수가 빈칸을 사이에 두고 주어진다. 이 값들은 모두 1 이상
www.acmicpc.net
- 예산들에 대해서 임의의 상한값을 잡고 매번 검사해야 하는데, 상한값의 범위가 크기 때문에 반씩 잘라서 유효성을 검사한다.
- 이분 탐색을 시작할 때 high 값은 예산들의 최댓값을 검사해도 되지만, low 값을 예산들의 최솟값으로 두고 검사할 경우 전체 예산의 상한액에 따라서 애초에 불가능할 수 있기 때문에 low 값을 0 부터 시작하는 것이 맞다.
- 어차피 상한값은 배열의 인덱싱과 상관없기 때문에, 배열 자체를 정렬할 필요는 없고 최댓값만 알고 있으면 된다.
#include <iostream>
#include <algorithm>
using namespace std;
int n;
int bud[10000];
unsigned long long m, answer;
int main(void)
{
cin >> n;
for(int i = 0 ; i < n ; i++)
{
cin >> bud[i];
answer += bud[i];
}
cin >> m;
sort(bud, bud + n); // 예산들 정렬
if(answer <= m) // 모든 요청이 배정될 수 있는 경우에는
{
cout << bud[n-1] << endl; // 요청한 금액 그대로 배정하고 최대예산 출력
return 0;
}
int low = 0, high = bud[n-1]; // 최솟값은 0, 최댓값은 최대예산으로 시작
// 최솟값을 최소예산으로 시작할 경우 논리적 오류 발생 가능
while(low <= high)
{
int mid = (low + high) / 2; // mid 를 상한액으로 잡고
unsigned long long total = 0;
for(int i = 0 ; i < n ; i++) // 예산을 집행했을 때
{
if(bud[i] < mid) total += bud[i];
else total += mid;
}
if(total <= m) // 집행이 가능한 경우라면
{
answer = mid; // 답을 갱신시켜주고
low = mid + 1; // 위쪽 이분탐색 실시
}
else // 불가능한 경우라면
{
high = mid - 1; // 아래쪽 이분탐색 실시
}
}
cout << answer << endl;
}
'PS > BOJ' 카테고리의 다른 글
[백준] 1058.py : 친구 (0) | 2020.12.26 |
---|---|
[백준] 1762 : 평면그래프와 삼각형 (0) | 2020.10.29 |
[백준] 10799 : 쇠막대기 (0) | 2020.09.23 |
[백준] 1946 : 신입 사원 (0) | 2020.09.17 |
[백준] 9934 : 완전 이진 트리 (0) | 2020.09.16 |