
출처
국가의 역할 중 하나는 여러 지방의 예산요청을 심사하여 국가의 예산을 분배하는 것이다. 국가예산의 총액은 미리 정해져 있어서 모든 예산요청을 배정해 주기는 어려울 수도 있다. 그래서 정해진 총액 이하에서 가능한 한 최대의 총 예산을 다음과 같은 방법으로 배정한다.
모든 요청이 배정될 수 있는 경우에는 요청한 금액을 그대로 배정한다.
모든 요청이 배정될 수 없는 경우에는 특정한 정수 상한액을 계산하여 그 이상인 예산요청에는 모두 상한액을 배정한다. 상한액 이하의 예산요청에 대해서는 요청한 금액을 그대로 배정한다.
예를 들어, 전체 국가예산이 485이고 4개 지방의 예산요청이 각각 120, 110, 140, 150이라고 하자. 이 경우, 상한액을 127로 잡으면, 위의 요청들에 대해서 각각 120, 110, 127, 127을 배정하고 그 합이 484로 가능한 최대가 된다.
여러 지방의 예산요청과 국가예산의 총액이 주어졌을 때, 위의 조건을 모두 만족하도록 예산을 배정하는 프로그램을 작성하시오.입력 4 120 110 140 150 485출력 127
# 입력
n = int(input()) # 예산을 할당받고자 하는 사람의 수
request_budgets = list(map(int, input().split())) # 예산 요청액들
limit_budget = int(input()) # 총 가용 예산
start = 1 # 시작 예산(최소값 1)
end = max(request_budgets)
max_budget = 0
while start<=end: # 종료조건
base_budget = (start+end) // 2
use_budget = 0
for budget in request_budgets:
if budget <= base_budget: # 사용하려는 예산이 기준 예산 이하라면
use_budget += budget # 사용하려는 예산만큼 더해도 됨.
else: # 예산이 기준예산보다 위라면 기준예산밖에 못 쓴다.
use_budget += base_budget
# 또는 예산이 너무 많아서 기준 예산을 쓸데없이 크게 잡은 경우
if use_budget > limit_budget: # 사용 예산이 리미트 예산 초과라면
end = base_budget - 1 # 사용할 예산 범위를 줄여야함.
else: # 사용 예산이 리미트 예산 이하라면
max_budget = base_budget # 사용한 예산은 무조건 리미트 예산 이하여야하기에 여기서 max값 업데이트
start = base_budget + 1 # 사용할 예산 범위를 늘려야함.
print(max_budget)
max기준 예산을 어디서 갱신 시킬것인가 범위는 어떻게 잡을 것인가 부등호 처리는 어떻게 할 것인가가 핵심인 문제였다.
처음에는 계속 틀렸었다.
if use_budget > limit_budget를 if use_budget >= limit_budget로 작성하고
max_budget = base_budget max값 갱신하는 부분을 예산 이상 부분에 두어서 답이 보다 1 크게 나오는 경우가 빈번했었다.
사용한 예산은 무조건 리미트 예산 이하여야하기에 else문에서 max값 업데이트를 하니 정답으로 처리가 되었다.
보다 제네럴하게 생각을 해야하며 왜 틀렸는지를 면밀하게 살펴봐야한다. 과연 이 부등호가 맞는가 여기서 값을 업데이트하는 것이 맞는가를 생각해야한다. 무작정 if문을 쓰기보다는 기존 조건에서 최대한 답이 되도록 생각해봐야겠다.
for budget in request_budgets:
if budget <= base_budget: # 사용하려는 예산이 기준 예산 이하라면
use_budget += budget # 사용하려는 예산만큼 더해도 됨.
else: # 예산이 기준예산보다 위라면 기준예산밖에 못 쓴다.
use_budget += base_budget
이 부분도 좀 더 짧게 쓸 수 있을 듯 하여
use_budget = sum(min(budget, base_budget) for budget in request_budgets)
이렇게 처리하는 과정을 후에 추가하였다. 요청된 budget이 기준 budget보다 크다면 base_budget로 처리하는 과정이다.