목차

기타 레슨

ps
링크acmicpc.net/…
출처BOJ
문제 번호2343
문제명기타 레슨
레벨실버 1
분류

파라메트릭 서치

시간복잡도O(min(n, mlogn) * lognk)
인풋사이즈n<=100,000, m<=100,000, k<=10000
사용한 언어Python
제출기록46368KB / 200ms
최고기록116ms
해결날짜2022/01/29

풀이

코드

코드 1 - O(n)의 결정함수

"""Solution code for "BOJ 2343. 기타 레슨".

- Problem link: https://www.acmicpc.net/problem/2343
- Solution link: http://www.teferi.net/ps/problems/boj/2343

Tags: [Parametric Search]
"""

from teflib import binsearch


def main():

    def is_valid(bluelay_len):
        bluray_count = 1
        cur_remaining_len = bluelay_len
        for l in lengths:
            if cur_remaining_len < l:
                bluray_count += 1
                cur_remaining_len = bluelay_len - l
            else:
                cur_remaining_len -= l
        return bluray_count <= M

    N, M = [int(x) for x in input().split()]  # pylint: disable=unused-variable
    lengths = [int(x) for x in input().split()]

    beg, end = max(lengths), sum(lengths) + 1
    print(binsearch.minimum_valid_integer(beg, end, is_valid))


if __name__ == '__main__':
    main()

코드 2 - O(mlogn)의 결정함수

"""Solution code for "BOJ 2343. 기타 레슨".

- Problem link: https://www.acmicpc.net/problem/2343
- Solution link: http://www.teferi.net/ps/problems/boj/2343

Tags: [Parametric Search]
"""

import bisect
from teflib import binsearch


def main():

    def is_valid(bluelay_len):
        pos = 0
        recorded_len = 0
        for _ in range(M):
            pos = bisect.bisect_right(acc_lengths,
                                      recorded_len + bluelay_len,
                                      lo=pos)
            if pos == N:
                return True
            recorded_len = acc_lengths[pos - 1]
        return False

    N, M = [int(x) for x in input().split()]
    lengths = [int(x) for x in input().split()]

    v = 0
    acc_lengths = [v := v + x for x in lengths]
    beg, end = max(lengths), sum(lengths) + 1
    print(binsearch.minimum_valid_integer(beg, end, is_valid))


if __name__ == '__main__':
    main()