Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

Python으로 창고에 넣을 수 있는 상자 개수 구하는 프로그램

문제 개요

정수로 이루어진 두 개의 배열이 있다고 가정해 보겠습니다. 하나는 단위 폭을 가진 상자들의 높이 목록이고, 다른 하나는 창고(godown)를 이루는 각 방의 높이 목록입니다. 방은 0부터 n까지 번호가 매겨져 있으며, 각 방의 높이는 godown 배열의 해당 인덱스에 저장되어 있습니다. 이때 창고에 밀어 넣을 수 있는 상자의 개수를 구하는 것이 과제입니다.

단, 다음 세 가지 조건을 반드시 기억해야 합니다.

  • 상자는 서로 위에 쌓을 수 없습니다.
  • 상자를 넣는 순서는 자유롭게 변경할 수 있습니다.
  • 상자는 왼쪽에서 오른쪽 방향으로만 넣을 수 있습니다.

만약 어떤 상자가 지나가야 할 방의 높이보다 크다면, 그 상자는 물론이고 그 오른쪽에 남은 모든 상자 역시 창고에 들어갈 수 없습니다.

입력 예시

예를 들어 boxes = [4, 5, 6], godown = [4, 5, 6, 7]이 주어졌다고 해 보겠습니다. 이 경우 출력은 1입니다. 첫 번째 방의 높이가 4이기 때문에 높이 4짜리 상자 하나만 들어갈 수 있고, 나머지 상자들은 반드시 첫 번째 방을 통과해야 하는데 그 방의 높이가 상자들보다 낮아 더 이상 넣을 수 없기 때문입니다.

Python으로 창고에 넣을 수 있는 상자 개수 구하는 프로그램

해결 아이디어

이 문제의 핵심은 "어떤 상자가 k번째 방에 도달하려면 0번방부터 k번방까지 모두 통과할 수 있어야 한다"는 점입니다. 따라서 k번째 방의 실효 높이는 godown[0..k] 구간의 최솟값, 즉 누적 최솟값(prefix minimum)이 됩니다.

이를 활용하면 그리디 전략으로 문제를 풀 수 있습니다. 작은 상자부터 순서대로, 실효 높이가 큰 방부터 배치하면 전체적으로 가장 많은 상자를 넣을 수 있습니다.

알고리즘 단계

  1. boxes 리스트를 오름차순으로 정렬합니다.
  2. godown의 첫 번째 값으로 curmin 리스트를 초기화하고, cm에 그 값을 저장합니다.
  3. i를 1부터 godown의 길이 - 1까지 순회하며 다음을 수행합니다.
    • cur := godown[i]
    • cur < cm이면 cm := cur로 갱신합니다.
    • cm을 curmin의 끝에 추가합니다. → curmin[j]는 j번째 방까지의 최소 높이를 의미합니다.
  4. 두 포인터 i := 0(상자 인덱스), j := godown 길이 - 1(방 인덱스), 결과 카운터 r := 0을 준비합니다.
  5. j >= 0이고 i < boxes 길이인 동안 반복합니다.
    • curmin[j] >= boxes[i]이면 해당 상자를 이 방에 넣을 수 있으므로 i와 r을 각각 1씩 증가시킵니다.
    • 매 반복마다 j를 1 감소시킵니다.
  6. 반복이 끝나면 r을 반환합니다. 이 값이 창고에 넣을 수 있는 상자의 최대 개수입니다.

Python 구현 예제

아래 코드를 통해 실제 동작을 확인해 보겠습니다.

def solve(boxes, godown):
    boxes.sort()
    curmin = [godown[0]]
    cm = curmin[0]
    for i in range(1, len(godown)):
        cur = godown[i]
        if cur < cm:
            cm = cur
        curmin.append(cm)
    i, j = 0, len(godown) - 1
    r = 0
    while j >= 0 and i < len(boxes):
        if curmin[j] >= boxes[i]:
            i += 1
            r += 1
        j -= 1
    return r

print(solve([4, 5, 6], [4, 5, 6, 7]))

입력

[4, 5, 6], [4, 5, 6, 7]

출력

1

복잡도 분석

상자 정렬에 O(n log n), 누적 최솟값 계산과 매칭에 O(m)(m은 방의 개수)이 소요되므로 전체 시간 복잡도는 O(n log n + m)입니다. 공간 복잡도는 누적 최솟값 배열을 저장하기 위해 O(m)입니다.