본문으로 바로가기

문제

지니레코드에서는 불세출의 가수 조영필의 라이브 동영상을 DVD로 만들어 판매하려 한다. DVD에는 총 N개의 곡이 들어가는데, DVD에 녹화할 때에는 라이브에서의 순서가 그대로 유지 되어야 한다. 순서가 바뀌는 것을 우리의 가수 조영필씨가 매우 싫어한다. 즉, 1번 노래와 5번 노래를 같은 DVD에 녹화하기 위해서는 1번과 5번 사이의 모든 노래도 같은 DVD에 녹화해야 한다. 또한 한 노래를 쪼개서 두 개의 DVD에 녹화하면 안된다.
지니레코드 입장에서는 이 DVD가 팔릴 것인지 확신할 수 없기 때문에 이 사업에 낭비되는 DVD를 가급적 줄이려고 한다. 고민 끝에 지니레코드는 M개의 DVD에 모든 동영상을 녹화하기 로 하였다. 이 때 DVD의 크기(녹화 가능한 길이)를 최소로 하려고 한다. 그리고 M개의 DVD는 모두 같은 크기여야 제조원가가 적게 들기 때문에 꼭 같은 크기로 해야 한다.

입력설명

첫째 줄에 자연수 N(1≤N≤1,000), M(1≤M≤N)이 주어진다. 다음 줄에는 조영필이 라이브에서 부른 순서대로 부른 곡의 길이가 분 단위로(자연수) 주어진다. 부른 곡의 길이는 10,000분을 넘지 않는다고 가정하자.

출력설명

첫 번째 줄부터 DVD의 최소 용량 크기를 출력하세요.

입력예제 1

9 3

1 2 3 4 5 6 7 8 9

출력예제 1

17

문제 풀이

import sys
sys.stdin = open("in5.txt", "rt")
n, m = map(int,input().split()) # 곡의 개수: n, 레코드의 개수: m
nlist = list(map(int,input().split())) # n개의 곡의 크기

start = max(nlist) # 최소값은 곡 중 제일 큰 값 
end = sum(nlist) # 최댓값은 곡의 합
res = 0 # 결과값을 저장하기 위해 변수 선언
maxx = max(nlist) # 곡의 최대 크기(레코드의 크기는 모든 곡을 담기 위해서는 곡의 최대 크기 이상이어야 한다.)

while start <= end:
    mid = (start+end)//2
    hap = 0
    cnt = 1
    for x in nlist:
        if hap + x > mid:
            cnt+=1
            hap = x
        else:
            hap+=x

    if cnt <= m and mid >= maxx:
        res = mid
        end = mid - 1
    else:
        start = mid + 1

print(res)


이분탐색 알고리즘을 사용하여 DVD의 크기의 최소값을 구합니다. while문을 도는 동안 DVD의 크기인 mid값에 최대한 담을 수 있는 레코드의 개수를 구합니다. 구한 값이 m보다 작거나 같고 mid값이 maxx보다 크거나 같은 경우만 레코드의 크기를 줄일 수 있으므로 end의 값을 mid-1로 합니다. 그 이외의 경우는 레코드의 크기가 커야 하므로 start값을 mid+1의 값으로 선언합니다. 마지막에 start가 end보다 크면 while문을 빠져나와 값을 출력합니다.

반응형