1931 회의실배정


문제

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

입력

첫째 줄에 회의의 수 n(1<=n<=100,000)이 주어진다. 둘째 줄부터 n+1 줄까지 각 회의의 정보가 주어지는데 이것은 공백을 사이에 두고 회의의 시작시간과 끝나는 시간이 주어진다. 시작 시간과 끝나는 시간은 231-1보다 작거나 같은 자연수 또는 0이다.

출력

첫째 줄에 최대 사용할 수 있는 회의 수를 출력하여라.

예제 입력 

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. 접근


주어진 조건 속에서 최대한 많은 회의를 골라야 한다. 그리디 알고리즘을 선택.


또는 각 회의를 넣을지 말지 2^n으로 탐색하거나,


동적 계획법으로 풀 수도 있다.


끝나는 시간순으로 회의들을 저장하는 confer[]배열을 정렬한 다음

ans(idx) = confer[idx] or 이전에 끝나는 회의들 중 최대한으로 선택할 수 있는 회의의 수 라는 함수를 만들자.


그러면 매 단계에서 ans()는 confer[idx]를 고를지 여부를 결정한다.

고른다면 confer[idx]가 될 것이고, 아니라면 1+ans(이전에 선택한 회의의 번호)가 되겠다.



2. 풀이


끝나는 시간 순으로 회의들을 정렬한 다음,


처음부터 회의들을 순회하면서 수행가능한 회의들로 갱신해 나간다.



3. 코드


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <algorithm>
using namespace std;
 
typedef pair<intint> p;
p confer[100000];
int n, i, m, cnt;
 
int main() {
    scanf("%d"&n);
    for (i = 0; i < n; ++i)
        scanf("%d %d"&confer[i].second, &confer[i].first);
    sort(confer, confer + n);
    cnt = 0;
    for (i = 0; i < n; ++i) {
        if (confer[i].second >= m) {
            cnt++;
            m = confer[i].first;
        }
    }
    printf("%d", cnt);
    return 0;
}
cs



4. 후기


그리디로 풀 수 있는 문제는 대부분 동적 계획법으로 풀 수 있다고 한다.

모든 단계를 고려하는 동적 계획법과 최적해만 고려하는 그리디는 본질적으로 같다.

다만 동적 계획법이 더 오래 걸리기 때문에 그리디를 사용한다.

'알고리즘 > Greedy 그리디' 카테고리의 다른 글

백준) 1911 흙길 보수하기  (0) 2017.07.25
백준) 1781 컵라면  (1) 2017.07.25
백준) 1946 신입 사원  (0) 2017.07.25
백준) 1744 수 묶기  (0) 2017.07.24
백준) 4796 캠핑  (0) 2017.07.23

+ Recent posts