[ 백준 ] 11000 / 강의실 배정

金弘均·2021년 9월 16일
0

Baekjoon Online Judge

목록 보기
227/228
post-thumbnail

# Appreciation

/*
 * Problem :: 11000 / 강의실 배정
 *
 * Kind :: Greedy + Data Structure
 *
 * Insight
 * - 일단 주어지는 수업들을 정렬해야 한다
 *   빨리 시작하고, 같이 시작한다면 빨리 끝나는 순서대로 수업들을 정렬한다
 *   + 최소의 강의실을 사용해서 수업들을 모두 가능하게 해야 하는데...
 *     각 강의실이 진행하고 있는 수업의 시작 시간과 종료 시간을 추적해야 한다
 *     # 그런데 일단 수업이 시작하면 그 수업의 종료 시간만 알아도
 *       다른 수업이 가능한지 알 수 있으므로 시작 시간까지는 추적할 필요가 없다
 *       -> 또한 각 강의실이 진행하고 있는 수업 중 가장 빨리 끝나는 수업의 시간만 알아도
 *          다음 수업이 현재 강의실만으로 가능한지 알 수 있다
 *          => 현재 강의실이 진행하고 있는 수업 중 가장 빨리 끝나는 수업의 시간이
 *             다음 수업이 시작하는 시간보다 같거나 작다면 다음 수업을 시작할 수 있고
 *             그렇지 않다면 다음 수업이 불가능하므로 강의실을 하나 더 늘려야 한다!
 *
 * - 항상 가장 빨리 수업이 끝나는 강의실을 알고 있어야 한다
 *   + 우선순위 큐를 활용하자!
 *     # 각 강의실에 번호를 붙여야 하는 것도 아니고 전체 강의실의 수만 알면 되므로
 *       강의실이 진행하고 있는 수업의 종료 시간만 저장해주자
 *       -> priority<int,vector<int>,greater<>> <= Min Heap
 *          int <= 수업 종료 시간
 *
 * Point
 * - less(default) 정렬에는
 *   operator < 가 정의되어 있어야 한다 <= 첫번째 인자를 기준으로 비교(<) 한다
 *   greater 정렬에는
 *   operator > 가 정의되어 있어야 한다 <= 첫번째 인자를 기준으로 비교(>) 한다
 *   + 우선순위 큐에서는 Min Heap 에는 greater 정렬이
 *     Max Heap 에는 less 정렬이 사용된다
 *     # 사실 좀 헷갈린다...
 *       Min Heap 에는 less 정렬이, Max Heap 에는 greater 정렬이 되야되는거 아닌가?
 *       -> 공식문서
 *          A priority queue is a container adaptor
 *          that provides constant time lookup of the largest (by default) element,
 *          at the expense of logarithmic insertion and extraction.
 *          A user-provided Compare can be supplied to change the ordering,
 *          e.g. using std::greater<T> would cause the smallest element
 *               to appear as the top().
 *          => 그렇다고 합니다...
 */

# Code

//
//  BOJ
//  ver.C++
//
//  Created by Rainy
//
//  Open Source

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

#define endl '\n'

// Set up : Global Variables
struct Course { int s, t; };

// Set up : Functions Declaration
bool operator < (Course u, Course v);


int main()
{
    // Set up : I/O
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    // Set up : Input
    int N; cin >> N;
    vector<Course> C(N);
    for (int i=0; i<N; i++)
        cin >> C[i].s >> C[i].t;

    // Process
    sort(C.begin(), C.end()); /* 빨리 시작하고 빨리 끝나는 순서대로 수업들 정렬 */
    /* 각 강의실 수업 종료 시간을 저장하는 우선순위 큐 */
    priority_queue<int,vector<int>,greater<>> R;
    R.push(0); /* 수업이 있다면 최소 1개의 강의실은 있어야 함 */
    for (int i=0; i<N; i++) {
        int s = C[i].s; /* i 번째 수업의 시작 시간 */
        int t = C[i].t; /* i 번째 수업의 종료 시간 */
        /* 강의실 중 가장 빨리 끝나는 수업의 종료 시간이 i 번째 수업의 시작 시간보다 빠르다면 */
        if (R.top() <= s) { /* 그 강의실을 i 번째 수업을 하는 강의실로 만듦 */
            R.pop();        /* 다만, R.top(0 = t 처럼
                             * R.top() 의 값을 바로 바꿀 수 없으므로 */
            R.push(t);      /* R.pop() 하고, R.push(t) 해주는 방식으로 정보를 갱신함 */
        }
        /* 강의실 중 가장 빨리 끝나는 수업의 종료 시간이 i 번째 수업의 시작 시간보다 느리다면 */
        else { R.push(t); } /* i 번째 수업을 하는 강의실을 추가 */
    }

    // Control : Output
    cout << R.size() << endl;
}

// Helper Functions
bool operator < (Course u, Course v)
/* Course 구조체를 정렬하기 위한 연산자 오버로딩 */
{
    return make_pair(u.s, u.t) < make_pair(v.s, v.t);
}
profile
이런 미친 게임을 봤나! - 옥냥이

0개의 댓글