알고리즘 풀이/백준(Boj)

백준(BOJ) 1931번 회의실배정

100win10 2019. 7. 19. 01:19

문제 : https://www.acmicpc.net/problem/1931


문제

한 개의 회의실이 있는데 이를 사용하고자 하는 N개의 회의들에 대하여 회의실 사용표를 만들려고 한다. 각 회의 I에 대해 시작시간과 끝나는 시간이 주어져 있고, 각 회의가 겹치지 않게 하면서 회의실을 사용할 수 있는 최대수의 회의를 찾아라. 단, 회의는 한번 시작하면 중간에 중단될 수 없으며 한 회의가 끝나는 것과 동시에 다음 회의가 시작될 수 있다. 회의의 시작시간과 끝나는 시간이 같을 수도 있다. 이 경우에는 시작하자마자 끝나는 것으로 생각하면 된다.


풀이:

회의가 끝나는 시간으로 오름차순으로 정렬한다. 정렬된 배열의 첫 번째 회의는 무조건 선택한다. 그 후 겹치는 회의를

지울 필요 없이 정렬된 배열을 순회하면서 첫 번째 회의와 겹치지 않는 회의를 찾자. 회의들은 오름차순으로 정렬되 있기 때문에

겹치지 않는 회의를 찾자마자 나머지를 보지 않고 선택하여도 된다.



코드 ( C++ ) 


#include <iostream>

#include <vector>

#include <algorithm>

#include <cstring>

#include <string>

using namespace std;

int n;

int schedule(int* begin, int* end) {

vector<pair<int, int>> order; // 일찍 끝나는 순서대로 정렬

for (int i = 0; i < n; ++i)

order.push_back({ end[i], begin[i]});

sort(order.begin(), order.end());

int earliest = 0, selected = 0; // earliest: 다음 회의가 시작할 수 있는 가장 빠른시간, selected: 지금까지 선택한 회의의 수

for (int i = 0; i < order.size(); ++i) {

int meetingEnd = order[i].first, meetingBegin = order[i].second; 

if (earliest <= meetingBegin){ // earliest를 마지막 회의가 끝난 시간 이후로 갱신

earliest = meetingEnd;

selected++;

}

}

return selected;

}

int main()

{

cin >> n;

int begin[100000], end[100000];

for (int i = 0; i < n; ++i)

cin >> begin[i] >> end[i];

int ans = schedule(begin, end);

cout << ans << endl;

}