본문 바로가기
백준

백준 10427: 빚(python)

by unhyepnhj 2025. 9. 26.

문제

 


풀이

 

설명을 복잡하게 해 놓아서 푸는 것보다 문제 읽는 게 더 어려웠다. 이래저래 설명해 놓긴 했는데, 요지는

 

빌린 돈들 중 M개를 골랐을 때:

  • 기본적으로 갚아야 하는 돈은 M개의 원금(이하 choice 배열이라 하겠음)
  • 갚아야 하는 돈은 M * max(choice)
  • 따라서, 추가적으로 더 갚아야 하는 돈은 M * max(choice) - sum(choice)

이다.

 

M은 상수, max(choice)는 그 구간의 최댓값이므로 M과 choice를 바꾸지 않는 한 건드릴 방법이 딱히 없다. 따라서 M * max(choice) - sum(choice)을 최소화하려면 sum(choice)를 최대화하는 수밖에 없고, 이 말은 곧 전체 빚 배열에서 max(choice)와 max(choice)보다 작은 것들 중 가장 큰 (M-1)개의 빚을 골라야 함을 뜻한다. 이는 오름차순 정렬된 빚 배열에서 크기가 M인 구간을 통째로 선택하는 것과 동일하므로 아래와 같이 처리한다. 

arr = list(map(int, input().split()))
ordered = sorted(arr[1:])
N = arr[0]

arr은 입력 배열, ordered는 arr에서 빚 배열 부분을 오름차순 정렬한 배열, 빚 개수 N은 arr 첫 번째 원소이다.

 

이후 1부터 N까지 모든 M에 대해 M마다 추가 금액인 additional을 계산하고 S(M)을 누적해야 하며, 앞선 설명 M * max(choice) - sum(choice)에서 max=ordered[i], sum(choice)=psum이다.

res = 0
for M in range(1, N + 1):
    temp = sys.maxsize

    for i in range(M - 1, N):   # ordered[i] 보다 작은 것들 중 (M - 1)개
        psum = sums[i + 1] - sums[i + 1 - M]
        additional = M * ordered[i] - psum

        if additional < temp:
            temp = additional
    res += temp

 

여기서 sums는 구간합 계산을 위한 구간합 배열이다. sums[i]=ordered[0]+ordered[1]+...+ordered[i-1]이므로, 정렬된 배열에서 i-M+1부터 i까지의 합은 sums[i+1]-sums[i+1-M]=psum으로 계산한 것이다.

 

위 과정을 거쳐 가능한 모든 구간에 대해 additional을 구하고, 구간 별 최소 추가 금액을 S(M)으로 선택한다.


전체 코드

import sys
input = sys.stdin.readline

T = int(input())
for _ in range(T):
    arr = list(map(int, input().split()))
    ordered = sorted(arr[1:])
    N = arr[0]

    sums = [0]
    for i in ordered:
        sums.append(sums[-1] + i)

    res = 0
    for M in range(1, N + 1):
        temp = sys.maxsize

        for i in range(M - 1, N):
            psum = sums[i + 1] - sums[i + 1 - M]
            additional = M * ordered[i] - psum

            if additional < temp:
                temp = additional
        res += temp

    print(res)

 

'백준' 카테고리의 다른 글

백준 22993: 서든어택 3(python)  (1) 2025.09.30
백준 1508: 레이스(python)  (0) 2025.09.26
백준 27377: 읽씹 멈춰! (python)  (0) 2025.08.22
백준 1074: Z(python)  (0) 2025.07.01
백준 14500: 테트로미노(python)  (0) 2025.06.30