poj 3190 优先队列+贪心

本文介绍了一种通过优先队列实现的牛挤奶调度算法,该算法能够确定最少需要多少个挤奶位(stall),并给出每头牛所在的挤奶位编号。通过对牛挤奶时间的排序和使用堆结构来跟踪挤奶位的使用情况,实现了资源的有效利用。
摘要由CSDN通过智能技术生成

题意:

有n头牛,分别给他们挤奶的时间。

然后每头牛挤奶的时候都要在一个stall里面,并且每个stall每次只能占用一头牛。

问最少需要多少个stall,并输出每头牛所在的stall。


e.g 样例:

INPUT:

5
1 10
2 4
3 6
5 8
4 7

OUTPUT:

4
1
2
3
2
4

HINT:

Explanation of the sample:

Here's a graphical schedule for this output:

Time     1  2  3  4  5  6  7  8  9 10

Stall 1 c1>>>>>>>>>>>>>>>>>>>>>>>>>>>

Stall 2 .. c2>>>>>> c4>>>>>>>>> .. ..

Stall 3 .. .. c3>>>>>>>>> .. .. .. ..

Stall 4 .. .. .. c5>>>>>>>>> .. .. ..
Other outputs using the same number of stalls are possible.


解析:

先将这些时间按照起始时间从小到大排序,然后用优先队列建立一个终止时间从小到大的堆。

每次比较堆顶,即终止时间最小的时间,与当前点起始时间的大小。

若小,则将当前这只牛加入到豪华午餐中。。。加入到堆顶这只牛的stall中。

若大,则自己另起炉灶,建立stall。


代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <map>
#include <climits>
#include <cassert>
#define LL long long
#define lson lo, mi, rt << 1
#define rson mi + 1, hi, rt << 1 | 1

using namespace std;
const int maxn = 5e4 + 10;
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;
const double pi = acos(-1.0);
const double ee = exp(1.0);

struct Node
{
    int st, ed;
    int id;
    bool operator < (const Node a) const
    {
        if (a.ed == ed)
            return a.st < st;
        return a.ed < ed;
    }
} cow[maxn];
int stall[maxn];

bool cmp(Node a, Node b)
{
    if (a.st == b.st)
        return a.ed < b.ed;
    return a.st < b.st;
}

int main()
{
    #ifdef LOCAL
    freopen("in.txt", "r", stdin);
    #endif // LOCAL
    int n;
    while (~scanf("%d", &n))
    {
        memset(stall, 0, sizeof(stall));
        for (int i = 0; i < n; i++)
        {
            scanf("%d%d", &cow[i].st, &cow[i].ed);
            cow[i].id = i;
        }
        sort(cow, cow + n, cmp);///按照起点排序
        priority_queue<Node> q;///按照终点建堆
        q.push(cow[0]);
        int cnt = 1;
        stall[cow[0].id] = 1;
        for (int i = 1; i < n; i++)
        {
            if (!q.empty() && q.top().ed < cow[i].st)
            {
                stall[cow[i].id] = stall[q.top().id];
                q.pop();
                q.push(cow[i]);
            }
            else
            {
                cnt++;
                stall[cow[i].id] = cnt;
                q.push(cow[i]);
            }
        }
        printf("%d\n", cnt);
        for (int i = 0; i < n; i++)
        {
            printf("%d\n", stall[i]);
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值