목차

시험장 나누기

ps
링크programmers.co.kr/…
출처프로그래머스
문제 번호81305
문제명시험장 나누기
레벨Level 5
분류

파라메트릭 서치

시간복잡도O(nlog(nm))
인풋사이즈n<=10,000, m<=10,000
사용한 언어Python
해결날짜2021/07/10
출처

ps:problems:programmers:2021_카카오_채용연계형_인턴십

풀이

코드

"""Solution code for "Programmers 81305. 시험장 나누기".

- Problem link: https://programmers.co.kr/learn/courses/30/lessons/81305
- Solution link: http://www.teferi.net/ps/problems/programmers/81305
"""

from teflib import algorithm


def solution(k, num, links):

    def can_make_group(group_size):
        dp = [0] * len(num)
        group_count = 1
        for node in nodes:
            c1, c2 = links[node]
            node_val = num[node]
            child_sum1 = dp[c1] if c1 != -1 else 0
            child_sum2 = dp[c2] if c2 != -1 else 0
            if child_sum1 + child_sum2 + node_val <= group_size:
                dp[node] = child_sum1 + child_sum2 + node_val
            elif min(child_sum1, child_sum2) + node_val <= group_size:
                dp[node] = min(child_sum1, child_sum2) + node_val
                group_count += 1
            else:
                dp[node] = node_val
                group_count += 2
            if group_count > k:
                return False
        return True

    parents = [None] * len(num)
    children_counts = []
    nodes = []
    for node, children in enumerate(links):
        children_count = 0
        for c in children:
            if c != -1:
                parents[c] = node
                children_count += 1
        children_counts.append(children_count)
        if children_count == 0:
            nodes.append(node)
    for i in range(len(num) - 1):
        p = parents[nodes[i]]
        children_counts[p] -= 1
        if children_counts[p] == 0:
            nodes.append(p)

    return algorithm.binary_search(max(num), sum(num) + 1, can_make_group)