Algorithm Problem Solving/SWExpertAcademy

Programming Advanced [파이썬 S/W 문제해결 구현03 탐욕 알고리즘] SWEA 5202 - 화물 도크 (D3)

cys4585 2021. 4. 20. 15:53

Problem

24시간 운영되는 물류센터에는 화물을 싣고 내리는 도크가 설치되어 있다.

0시부터 다음날 0시 이전까지 A도크의 사용신청을 확인해 최대한 많은 화물차가 화물을 싣고 내릴 수 있도록 하면, 최대 몇 대의 화물차가 이용할 수 있는지 알아내 출력하는 프로그램을 만드시오.

신청서에는 작업 시작 시간과 완료 시간이 매시 정각을 기준으로 표시되어 있고, 앞 작업의 종료와 동시에 다음 작업을 시작할 수 있다.

예를 들어 앞 작업의 종료 시간이 5시면 다음 작업의 시작 시간은 5시부터 가능하다.


[입력]

첫 줄에 테스트케이스의 수 T가 주어진다. 1<=T<=50

다음 줄부터 테스트 케이스의 별로 첫 줄에 신청서 N이 주어지고, 다음 줄부터 N개의 줄에 걸쳐 화물차의 작업 시작 시간 s와 종료 시간 e가 주어진다.

1<=N<=100, 0<=s<24, 0 < e <= 24 


[출력]

각 줄마다 "#T" (T는 테스트 케이스 번호)를 출력한 뒤, 답을 출력한다.
 

Solving

아이디어

  1. 0~24시 까지의 배열을 만들어서 도크 작업이 진행되는 시간대를 채워나가는 식으로 진행
  2. 중복되지 않도록 도크 작업을 하는 화물을 체크
  3. 매 탐색마다 가장 짧게 작업하는 화물을 찾아서, 작업하는 시간을 채우고, 체크표시 하고, 카운팅 하고, 다시 탐색한다. 매 탐색마다 가장 짧게 작업하는 경우를 카운팅 하다 보면, 결국 가장 많이 작업할 수 있는 수를 알아낼 수 있다.
  4. 탐색에서 작업 가능한 화물을 찾지 못하면, 이 때까지 한 카운팅이 최대 카운팅

코드

def function(cnt):
    global max_cnt
    # 가장 적게 이용하는 화물을 찾을 변수
    min_usage_time = 987654321
    idx = 0
    for i in range(N):
        # 작업에 포함된 화물은 pass
        if checked[i]: continue
        tmp_start, tmp_end = start_end[i]
        # 해당 화물이 차지하는 작업 시간이
        # 이미 다른 화물에 할당되어 있으면 break
        # 즉, 해당 화물은 작업 가능하지 않다면 break
        for t in range(tmp_start, tmp_end):
            if time[t]:
                break
        # 해당 화물이 작업 가능하다면
        else:
            # 남은 화물 중에서 해당 화물이 가장 적게 이용하는 경우라면 갱신
            tmp_time = tmp_end - tmp_start
            if min_usage_time > tmp_time:
                min_usage_time = tmp_time
                idx = i
    # 값이 갱신되지 않았다면, 더이상 작업할 수 있는 화물이 없다는 뜻
    if min_usage_time == 987654321:
        return cnt

    # 값이 갱신되었다면, 해당 화물을 체크하고, 시간을 할당한다.
    checked[idx] = 1
    start, end = start_end[idx]
    for t in range(start, end):
        time[t] = 1
    # 재귀 (남은 화물 가지고 다시 조사)
    return function(cnt + 1)


for tc in range(1, int(input()) + 1):
    N = int(input())
    # [시작시간, 종료시간]
    start_end = [list(map(int, input().split())) for _ in range(N)]

    time = [0] * 25     # 0시 ~ 24시
    checked = [0] * N   # 작업 가능한 화물 체크

    print(f'#{tc} {function(0)}')