CodeLog
[그리디 알고리즘] 백준 1931번 회의실 배정 본문
문제
한 개의 회의실이 있는데 이를 사용하고자 하는 N개의 회의에 대하여 회의실 사용표를 만들려고 한다. 각 회의 I에 대해 시작시간과 끝나는 시간이 주어져 있고, 각 회의가 겹치지 않게 하면서 회의실을 사용할 수 있는 회의의 최대 개수를 찾아보자. 단, 회의는 한번 시작하면 중간에 중단될 수 없으며 한 회의가 끝나는 것과 동시에 다음 회의가 시작될 수 있다. 회의의 시작시간과 끝나는 시간이 같을 수도 있다. 이 경우에는 시작하자마자 끝나는 것으로 생각하면 된다.
입력
첫째 줄에 회의의 수 N(1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N+1 줄까지 각 회의의 정보가 주어지는데 이것은 공백을 사이에 두고 회의의 시작시간과 끝나는 시간이 주어진다. 시작 시간과 끝나는 시간은 2^31-1보다 작거나 같은 자연수 또는 0이다.
출력
첫째 줄에 최대 사용할 수 있는 회의의 최대 개수를 출력한다.
예제
예제 입력 1 | 예제 출력 1 |
11 1 4 3 5 0 6 5 7 3 8 5 9 6 10 8 11 8 12 2 13 12 14 |
4 |
아이디어
회의가 끝나는 시간이 빠른 순서로 회의를 배정할 경우 가장 많은 회의를 진행할 수 있다. 현재 최적해는 배정 가능한 최대 회의의 수를 구하는 것이다. 각 단계의 최적 선택은 이전까지 배정한 회의를 기준으로 종료 시간이 가장 빠른 다른 회의를 배정하는 것이다.
따라서 우선 회의를 종료 시간 기준으로 정렬해야 한다. 이전에 배정한 회의의 종료 시간을 변수에 저장해두고 현재 회의의 시작 시간을 비교한다. 현재 회의를 배정할 수 있다면(이전 회의들의 종료시간 <= 현재 회의의 시작 시간) 회의를 배정한 후 현재 회의의 종료 시간을 다시 변수에 저장하고 배정 가능한 회의의 수에 1을 더한다. 이러한 작업을 모든 회의에 대해 반복하면 최적해를 구할 수 있다.
변수 설명(솔루션과 코드)
N: 주어지는 회의의 수
M: 모든 회의의 시작, 종료 시간을 저장하는 배열
end: 이전 단계에서 배정된 회의의 종료 시간을 저장하는 변수(초기 값은 0)
mcount: 현재까지 배정된 회의의 수를 카운트하는 변수(초기 값은 0)
솔루션
M에 저장된 회의의 시작, 종료 시간을 회의의 종료 시간을 기준으로 정렬한다. for문을 통해 현재 배정된 회의의 종료 시간인 end와 현재 회의의 시작시간인 M[i][0]을 비교한다. 이때 end가 M[i][0]보다 작거나 같은 경우 현재 회의를 배정할 수 있기 때문에 end의 값을 M[i][1]로 변경하고 mcount에 1을 더한다. 이러한 과정을 N번 반복하면 주어진 회의 중 배정 가능한 회의의 최대 수를 구할 수 있다.
코드(Python)
import sys
N = int(input())
M = []
end, mcount = 0, 0
for i in range(N):
M.append(list(map(int,sys.stdin.readline().split())))
M = sorted(M,key = lambda x: (x[1],x[0]))
for i in range(N):
if end <= M[i][0]:
mcount += 1
end = M[i][1]
print(mcount)
설명에 잘못된 부분이 있거나 질문 사항이 있으시다면 언제든지 댓글 남겨주세요 :)
'Algorithm > Greedy Algorithm' 카테고리의 다른 글
[그리디 알고리즘] 백준 11000번 강의실 배정 (0) | 2020.08.28 |
---|---|
[그리디 알고리즘] 백준 1783번 병든 나이트 (1) | 2020.08.26 |
[그리디 알고리즘] 백준 10610번 30 (0) | 2020.08.26 |
[그리디 알고리즘] 백준 2875번 대회 or 인턴 (0) | 2020.08.26 |
[그리디 알고리즘] 백준 11047번 동전0 (0) | 2020.08.26 |