[ 문제 풀이 ]
- Problem : 백준 #11000
- 구분 : Greedy, pq(우선순위 큐), ds
- 난이도 : Gold 5
- 풀이 방법 :
- 한 강의실 당 강의 시간이 겹치지 않는 수업을 최대한 몰아줘야 최소 강의실 개수를 구할 수 있습니다.
- 강의실에 시작 시간이 빠른 것 수업부터 조사해서 같은 강의 실에 넣을 수 있는지 판단해 강의실을 할당하는 그리디 알고리즘(현재 조건에서 가장 최선의 경우를 할당)을 사용했습니다.
- (시작 시간, 종료 시간)으로 구성된 수업을 pq에 넣고, 시작 시간이 빠른 것부터 정렬하도록 했습니다. (만약, 시작 시간이 같다면 종료 시간이 가장 빠른 순서대로 정렬하도록 구성했습니다.)
- 수업 시작 시간은 이미 정렬이 된 상태이기 때문에 종료시간과 다음 수업 시작 시간을 비교하기 위해 종료 시간을 저장할 pq를 하나 더 선언해 주었습니다. 여기서 pq 내부의 한개의 요소는
강의실
을 의미합니다.
- 수업을 한개씩 pq에서 빼면서, 다음과 같은 로직을 따르게 했습니다.
- 강의실 우선순위 큐(tq)가 비었다면, 현재 강의실이 0개이므로 강의실을 생성해 해당 수업을 할당합니다.
👉🏻 종료시간을 tq에 저장합니다.
- 강의실 우선순위 큐(tq)가 비어있지 않다면, 현재 강의실 중 종료 시간이 가장 이른 강의실(tq.top())의 종료시간과 현재 수업의 시작 시간을 비교합니다.
- 만약 종료시간이 현재 수업의 시작 시간보다 작거나 같다면, 해당 수업은 강의실의 기존 수업과 겹치지 않으므로 할당할 수 있습니다.
👉🏻 해당 강의실의 종료시간을 갱신해줍니다.
- 만약 종료시간이 현재 수업의 시작 시간보다 크다면, 해당 강의실의 수업과 겹치므로 할당할 수 없습니다.
👉🏻 새로운 강의실을 생성해 해당 수업을 할당합니다.
- 강의실 배정이 끝나면
tq.size() = 강의실의 개수
를 출력해줍니다.
- 해당 알고리즘의 시간복잡도는
O(nlogn)
입니다.
[ 🤟🏻 code from ss-won ]
#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
#include <queue>
using namespace std;
struct compare{
bool operator()(pair<int,int> a, pair<int,int> b){
if(a.first == b.first){
return a.second > b.second;
}
return a.first > b.first;
}
};
priority_queue<pair<int,int>, vector<pair<int,int>>, compare> pq;
priority_queue<int, vector<int>, greater<int>> tq;
int n, s, t;
int main() {
ios_base :: sync_with_stdio(false);
cin.tie(NULL);
cin >> n;
while(n--){
cin >> s >> t;
pq.push({s,t});
}
while(!pq.empty()){
tie(s,t) = pq.top(); pq.pop();
if(tq.empty()){
tq.push(t);
}
else{
if(s >= tq.top()){
tq.pop();
tq.push(t);
}
else{
tq.push(t);
}
}
}
cout << tq.size();
return 0;
}x