Stall Reservations (a greedy algorithm) - Study Notes

Problem Description

N-cattle (1 <= n <= 50,000 ) to be milked. Given time each cow milking zone
between [A, B] (1 < = A <= B <= 1,000,000, A, B is an integer).
Cattle need to stay milking corral. A corral at the same time it can only accommodate a cow.
Q. How many corrals at least, to complete all the milking, and each head of cattle which have put the corral (Special judged)
to a corral with two cows, which are milked time interval even if the endpoint is not just coincidence possible.

how are you

Here, all our cows need milking, milking a cow when to, it is necessary to look for the cows.

S (x) represents a start time x of cows. E (x) indicates the end of time x. Of E (x), x can be cows, can also be a corral. End Time corral the end of time, is that there are milking cows. The same time the end of the corral is constantly varying.

Outline of Solution
1: The cow milking sorted from front to back start time
2: assignment of a first cow stalls
3: sequentially processing each cow behind, i Treatment cows, consider assigned stall has ended the first time corral x.
When the end of a stall time <start time of the cows, not the allocation of new stalls, I can enter x, and modify the stall end time E (i)
If the stall end time> = cows start time, allocating a new animal bar, E (i)
until all the cows processing ends

Points

Need to use the priority queue to store corral already assigned, so that the end times and always at the earliest corral head of the queue.

#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
struct Cow {//奶牛
    int a, b; //挤奶区间起终点
    int No; //编号
    bool operator<(const Cow& c) const {
        return a < c.a;//按照开始时间从早到晚排序
    }
} cows[50100];
int pos[50100]; //pos[i]表示编号为i的奶牛去的畜栏编号
struct Stall {//畜栏
    int end; //结束时间
    int No; //编号
    bool operator<(const Stall& s) const {
        return end > s.end;//按照畜栏的结束时间排序
    }
    Stall(int e, int n) :end(e), No(n) { }
};
int main()
{
    int n;
    cin>>n;
    for (int i = 0; i < n; ++i) {
        cin>>cows[i].a>>cows[i].b;
        cows[i].No = i;
    }
    sort(cows, cows + n);
    int total = 0;
    priority_queue<Stall> pq;//畜栏的队列
    for (int i = 0; i < n; ++i) {
        if (pq.empty()) {//如果畜栏为空的话,就是放入第一个畜栏
            ++total;
            pq.push(Stall(cows[i].b, total));//并且新开一个畜栏,以放入当前奶牛的结束时间为畜栏的结束时间
            pos[cows[i].No] = total;
        }
        else {
            Stall st = pq.top();//指向队列的顶端,即即将释放的畜栏
            if (st.end < cows[i].a) { //端点也不能重合////如果畜栏的结束时间早于奶牛的开始时间的话
                pq.pop();
                pos[cows[i].No] = st.No;
                pq.push(Stall(cows[i].b, st.No));
            }
            else { //对应 if( st.end < cows[i].a //畜栏的结束时间晚于奶牛的开始时间,即队列中没有可以释放的畜栏,就新开一个畜栏放入奶牛
                ++total;
                pq.push(Stall{cows[i].b,total });//畜栏结束时间设置为奶牛结束
                pos[cows[i].No] = total;
            }
        }
    }
    cout << total << endl;
    for (int i = 0; i < n; ++i)
        cout << pos[i] << endl;
    return 0;
}
Published 97 original articles · won praise 208 · views 70000 +

Guess you like

Origin blog.csdn.net/weixin_45822638/article/details/105272109