111. 畜栏预定(贪心,区间分组)

 

 贪心:按照左端点排序(开始吃草时间),每一次都寻找能放入的栅栏中,结束时间最早的一个

关于为什么选择左端点排序,详见区间分组

这里和区间分组不同的点在于,我们不仅要维护一个畜栏的最小右端点,我们还需要知道,每个牛他都被分配到了哪里,因为我们知道牛排序后编号会乱套,所以要在结构体内加上他的编号

#include <iostream>
#include <algorithm>
#include <queue>
#define x first
#define y second
using namespace std;
const int N = 50000 + 10;
struct node
{
    int l, r;
    int note;   //排序后会乱序,需要加note
    bool operator <(const node b)const
    {
        return l < b.l;
    }
}a[N];
typedef pair<int, int> PII;
//PII  x 记录最小右端点  y 记录是哪一个栅栏
int q[N];
int main()
{
    int n;
    cin >> n;
    for (int i = 0;i < n;i++)
    {
        cin >> a[i].l >> a[i].r;
        a[i].note = i+1;
    }
    sort(a, a + n);
    priority_queue<PII, vector<PII>, greater<PII> > heap;
    for (int i = 0;i < n;i++)
    {
        if (!heap.size() || heap.top().x >= a[i].l)
        {//需要多开一组
        //这里注意一下畜栏的时间允不允许重合,允许>,不允许>=
            q[a[i].note] = heap.size() + 1;
            heap.push({ a[i].r,heap.size() + 1 });//新开一个畜栏
        }
        else
        {
            auto t = heap.top();
            q[a[i].note] = t.y; //记录这头牛的畜栏
            heap.pop();   //出队
            heap.push({ a[i].r,t.y });//继承出来那头牛的畜栏
        }
    }
    cout << heap.size()<<'\n';
    for (int i = 1;i <= n;i++)
        cout << q[i] << '\n';
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值