접근
이 문제 역시 1946번과 같이 제한 시간 내에 풀기 위해서는 O(N^2)이 되면 안된다. 강의실의 개수를 최소로 사용하기 위해서는 최대한 많은 수업이 연속해서 일어나야 한다. 즉, 최대한 (앞 수업의 종료 시간) <= (뒷 수업의 시작 시간)이 되도록 만들어야 한다.
우선 수업 시간의 시작 시간이 가장 빠른 순서대로, 만약 시작 시간이 같다면 종료 시간이 빠른 순서대로 정렬한다. 그 뒤에 앞선 수업들의 종료시간 중 가장 빨리 끝나는 값과 현재 수업의 시작 시간을 비교하면 된다. (우선순위 큐를 사용한다는 의미) 모든 연산이 종료되고 나면, pq의 사이즈값이 곧 사용하는 강의실의 최소 개수가 된다.
(1, 2), (1, 7), (2, 4), (5, 6) 총 4개의 강의가 있다고 해보자. 결론부터 말하면 (1, 2)~(2, 4)~(5, 6) / (1, 7) 으로 총 2개의 강의실을 사용하게 된다.
먼저 첫 강의는 무조건 빈 강의실에 배정될 수 있으므로, 해당 종료 시간이 그대로 pq에 들어간다.
(1, 2), (1, 7), (2, 4), (5, 6)
endTime(pq): 2
두 번째 강의의 경우, 앞선 강의의 종료시간보다 시작시간이 빠르기 때문에 같은 강의실을 사용할 수 없다. 따라서 해당 강의의 종료 시간을 pq에 넣어준다.
(1, 2), (1, 7), (2, 4), (5, 6)
endTime(pq): 2, 7
세 번째 강의의 경우, pq에서 꺼낸 값이 2로 시작 시간과 동일하므로 같은 강의실을 사용할 수 있다. 2값을 빼고 이어서 진행되는 수업의 종료 시간을 넣는다.
(1, 2), (1, 7), (2, 4), (5, 6)
endTime(pq): 4, 7
마지막 강의의 경우, pq에서 꺼낸 값이 4로 시작 시간인 5보다 작기 때문에 같은 강의실을 사용할 수 있다. 4를 빼고 6을 넣어준다.
(1, 2), (1, 7), (2, 4), (5, 6)
endTime(pq): 6, 7
모든 계산을 마치고 나면, 처음에 예시와 함께 보았던 강의실의 마지막 수업 종료 시간과 pq에 들어있는 값이 일치하게 된다. 즉, pq의 사이즈가 곧 필요한 강의실의 개수가 되는 것을 확인했다.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class BJ11000 {
static class Table implements Comparable<Table>{
int s, t;
Table(int s, int t){
this.s = s;
this.t = t;
}
// 시작 시간이 빠른 순서대로, 같다면 빨리 끝나는 순으로 정렬
@Override
public int compareTo(Table o) {
if(this.s == o.s)
return this.t - o.t;
else return this.s - o.s;
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = null;
int n = Integer.parseInt(br.readLine());
PriorityQueue<Table> tables = new PriorityQueue<>();
// 입력값 저장
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
int s = Integer.parseInt(st.nextToken());
int t = Integer.parseInt(st.nextToken());
tables.add(new Table(s, t));
}
// 최소 강의실 개수 계산
PriorityQueue<Integer> pq = new PriorityQueue<>();
pq.add(0);
while (!tables.isEmpty()){
Table cur = tables.poll();
int earliestEndTime = pq.peek();
if(cur.s >= earliestEndTime) pq.poll();
pq.add(cur.t);
}
System.out.println(pq.size());
}
}
'Algorithm' 카테고리의 다른 글
[백준] 2812: 크게 만들기 JAVA (0) | 2023.01.31 |
---|---|
[백준] 1715: 카드 정렬하기 JAVA (0) | 2023.01.30 |
[백준] 1946: 신입 사원 JAVA (0) | 2023.01.28 |
[백준] 16953: A → B JAVA (0) | 2023.01.28 |
[백준] 2473: 세 용액 JAVA (0) | 2023.01.18 |