【ybtoj】【贪心】【堆】【例题3】畜栏预定

【例题3】畜栏预定

>link

传送门
题目


>解题思路

以奶牛开始吃草时间排序

  • 如果当前奶牛可以接到一个畜栏后面,就往上接
  • 如果没有一个畜栏可以接,就为这头奶牛新建一个畜栏

可以发现,只要畜栏的最后一头奶牛结束吃草时间越早,接上奶牛的可能性就越大
用小根堆,以畜栏的结束吃草时间实时排序


>Code

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <queue>

using namespace std;

struct DT {
    
    
    int x, y, i;
} a[50100], t;
int n, ans[50100], num;

bool cmp(const DT& k, const DT& l) {
    
    
    if (k.x == l.x)
        return (k.y < l.y);
    return (k.x < l.x);
}

//小根堆用结构体的用法(我也不懂为什么这么写)
bool operator<(DT a, DT b) {
    
     return a.y > b.y; }//以结束吃草时间排序
                           //return a.y < b.y;  就是大根堆了,好奇妙

int main() {
    
    
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
    
    
        scanf("%d%d", &a[i].x, &a[i].y);
        a[i].i = i;
    }
    sort(a + 1, a + 1 + n, cmp);
    priority_queue<DT> f;
    f.push(a[1]), ans[a[1].i] = ++num;//ans标记在哪个畜栏里
    for (int i = 2; i <= n; i++) {
    
    
        t = f.top();
        if (a[i].x <= t.y)//如果最早吃完的畜栏也接不上这头牛
            f.push(a[i]), ans[a[i].i] = ++num;//新建一个畜栏
        else {
    
    //接的上就往上接
            f.pop();
            t.y = a[i].y, ans[a[i].i] = t.i;//更新这个畜栏的结束吃草时间
            f.push(t);
        }
    }
    printf("%d\n", f.size());
    for (int i = 1; i <= n; i++) printf("%d\n", ans[i]);
}

猜你喜欢

转载自blog.csdn.net/qq_39940018/article/details/111714937