코딩테스트 대비/백준 알고리즘

BOJ - 2512 예산

JellyApple 2024. 10. 15. 23:41

문제 링크 : https://www.acmicpc.net/problem/2512

문제 티어 : 실버2

문제 유형 : 이진 탐색

문제 풀이
 한정된 값을 최대한의 예산으로 나누어 주어야 한다.

1) 적절한 상한금액을 찾는 것이 목표
2) 배정을 다하고도 남는 예산이 0이상이어야함

3) 남은 예산이 0에 가까워야 함

 

이진 탐색 방법으로 생각하면 양 쪽 끝을 기준으로 최댓값과 최솟값을 잡고 그 사이를 점점 간격을 좁혀 나가면서 예산의 최댓값을 찾아주는 것이 핵심이다. 예를 들면 아래와 같다. 

1) 최솟값 = 0 , 최댓값 = Math.max()  , mid = (최솟값 + 최댓값 ) / 2

2) 만약 배정된 예산의 총합이 mid 보다 크면 상한액을 줄여야 하므로 mid를 -1 해서 점점 줄임

3) 만약 배정된 예산의 총합이 mid 보다 작거나 같으면 상한액을 높여도 되므로 상한액 범위를 올린다.

 

위 풀이를 코드로 표현하면 아래와 같다.

const fs = require("fs");
let input = fs.readFileSync("/dev/stdin").toString().split("\n");
let N = Number(input[0]);
let arr = input[1].split(" ").map(Number);
let M = Number(input[2]);

// 이진 탐색 분류
let start = 1; // 시작점
let end = arr.reduce((a,b) => Math.max(a,b)); // 최댓값 끝 점
let result = 0; // 결괏값을 담을 변수

while(start<=end){
    let mid = parseInt((start+end)/2);
    let total = 0; // 배정된 예산 총액
    // arr 순회해서 예산 모두 더해줌
    for(x of arr) {
        total+=Math.min(mid,x); // 만약 mid가 더 작으면 mid 그게 아니면 x를 total에 반영
    }
    // 만약 총액이 배정된 예산보다 적은 경우
    if(total<=M) {
        result = mid;
        start = mid+1;
    } else {
        end = mid - 1;
        }
 }
 console.log(result);

 

시간복잡도 : 입력처리 : O(N) + 이진탐색 부분 : while -> O(log M) , for 루프 -> O(N) => O(NlogM) 

'코딩테스트 대비 > 백준 알고리즘' 카테고리의 다른 글

BOJ - 1654 랜선 자르기  (0) 2024.11.17
BOJ - 2805 나무 자르기  (0) 2024.11.17
BOJ - 19939 박 터트리기  (4) 2024.10.09
BOJ - 9009 피보나치  (0) 2024.10.08
BOJ - 1931 회의실 배정  (0) 2024.07.14