백준 2512 예산

피나코·2021년 9월 21일
1

알고리즘

목록 보기
14/46

문제 바로가기

문제

국가의 역할 중 하나는 여러 지방의 예산요청을 심사하여 국가의 예산을 분배하는 것이다. 국가예산의 총액은 미리 정해져 있어서 모든 예산요청을 배정해 주기는 어려울 수도 있다.
그래서 정해진 총액 이하에서 가능한 한 최대의 총 예산을 다음과 같은 방법으로 배정한다.
모든 요청이 배정될 수 있는 경우에는 요청한 금액을 그대로 배정한다.
모든 요청이 배정될 수 없는 경우에는 특정한 정수 상한액을 계산하여 그 이상인 예산요청에는 모두 상한액을 배정한다. 상한액 이하의 예산요청에 대해서는 요청한 금액을 그대로 배정한다.
예를 들어, 전체 국가예산이 485이고 4개 지방의 예산요청이 각각 120, 110, 140, 150이라고 하자. 이 경우, 상한액을 127로 잡으면, 위의 요청들에 대해서 각각 120, 110, 127, 127을 배정하고 그 합이 484로 가능한 최대가 된다.
여러 지방의 예산요청과 국가예산의 총액이 주어졌을 때, 위의 조건을 모두 만족하도록 예산을 배정하는 프로그램을 작성하시오.

입력

첫째 줄에는 지방의 수를 의미하는 정수 N이 주어진다. N은 3 이상 10,000 이하이다. 다음 줄에는 각 지방의 예산요청을 표현하는 N개의 정수가 빈칸을 사이에 두고 주어진다. 이 값들은 모두 1 이상 100,000 이하이다. 그 다음 줄에는 총 예산을 나타내는 정수 M이 주어진다. M은 N 이상 1,000,000,000 이하이다.

접근방법

초반 접근으로는 인풋으로 들어온 요청금액들의 평균을 활용 해보자 였는데, 평균값을 기준으로 반복문을 돌아 예산을 계산하고, 제한선보다 크면 평균-- 작으면 평균++을 하는 방법이다.하지만 정답과 평균의 거리가 멀다면 평균--를 하면서 답까지 도달하도록 코드를 짜면 시간초과가 날것같았다.
두번째 접근으로는 상한액을 들어온 인풋 수로 나눈 금액을 기준으로 하는건데 위의 평균을 기준으로 한 방법과 동일했다..

뭔가 공식이 있을것만같아서 좀 더 고민해봤지만 찾아낼 수 없었다. 그렇다면 일일이 값을 구해야 하는것인데 특정 범위내에서 값을 빨리 찾는 방법... 그렇다 이분탐색을 쓰면된다!!

우선 이분탐색을 하기위해선 인풋값들이 정렬이 되어있어야하므로 미리 정렬을 해준 후 이분탐색을 해주었다.

public class Main_2512_예산 {
	static int maxV;

	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int N = Integer.parseInt(br.readLine());
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		int arr[] = new int[N];
		for (int i = 0; i < N; i++) {
			arr[i] = Integer.parseInt(st.nextToken());
		}
		long budget = Long.parseLong(br.readLine());
		Arrays.sort(arr);

		int start = 0;
		int end = arr[N - 1];

	
		while (start <= end) {
			int mid = (start + end) / 2;
			long bud = 0;
			for (int i = 0; i < N; i++) {
				if (arr[i] <= mid)
					bud += arr[i];
				else
					bud += mid;
			}
			if (bud <= budget) {
				maxV = Math.max(maxV, mid);
				start = mid + 1;
			} else
				end = mid - 1;
		}
		System.out.println(maxV);
	}
}
profile
_thisispinako_

0개의 댓글