POJ 3190 Stall Reservations (选择不相交区间)

Description

Oh those picky N (1 <= N <= 50,000) cows! They are so picky that each one will only be milked over some precise time interval A..B (1 <= A <= B <= 1,000,000), which includes both times A and B. Obviously, FJ must create a reservation system to determine which stall each cow can be assigned for her milking time. Of course, no cow will share such a private moment with other cows.

Help FJ by determining:
The minimum number of stalls required in the barn so that each cow can have her private milking period
An assignment of cows to these stalls over time
Many answers are correct for each test dataset; a program will grade your answer.
Input

Line 1: A single integer, N

Lines 2..N+1: Line i+1 describes cow i’s milking interval with two space-separated integers.
Output

Line 1: The minimum number of stalls the barn must have.

Lines 2..N+1: Line i+1 describes the stall to which cow i will be assigned for her milking period.
Sample Input

5
1 10
2 4
3 6
5 8
4 7
Sample Output

4
1
2
3
2
4

题目大意:
农夫有N头奶牛,每头奶牛有自己的产奶时间A到B,每头牛产奶时必须单独为它安排一间畜栏,不得同时共用一间,要求根据每头牛的产奶时间,安排一个合理的方案使得使用畜栏数最少。

解题思路:
明显要先处理产奶时间靠前并且结束时间靠前的奶牛,这样才能使后面的奶牛接着使用同一畜栏。
首先对结构体按照开始时间升序排列。这样从0~N找时只要判断该奶牛的起始时间是否比前面每个畜栏的最小的终止时间大,如果大的话,就可以安排在其后面产奶,并且更新该畜栏的终止时间。如果小的话,则必须新开一间畜栏。
因为一直要找最小值,考虑使用优先队列(priority_queue),结束时间小的优先级高。这样比较方便找最小值。
需要注意的是两头奶牛的开始时间和结束时间相同时不能放在同一个畜栏。
第一次做时不知道用堆来维护最小值,写了个暴力的算法,超时了。这应该是我第一次用优先队列吧,且学且珍惜。
也可另开一个数组存放每只奶牛对应的stall值,这样就省去了再一次sort的时间。

#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;

typedef struct node
{
    int b,e,stall,id;
    friend bool operator< (node n1,node n2)
    {
        return n1.e > n2.e;
    }
}cow;
cow s[50005];

bool cmp1(cow x,cow y)
{
    return x.b < y.b;
}

bool cmp2(cow x,cow y)
{
    return x.id < y.id;
}

int main()
{
    int N;
    while(~scanf("%d",&N))
    {
        for(int i = 0;i < N;i++)
        {
            scanf("%d%d",&s[i].b,&s[i].e);
            s[i].id = i;
        }
        sort(s,s+N,cmp1);

        priority_queue<cow> que;
        s[0].stall = 1;//第一次将这句写在了push的后面,WA了,应引起注意,先初始化再加入堆
        que.push(s[0]);
        int cnt = 1;

        for(int i = 1;i < N;i++)
        {
           cow temp = que.top();
           {
               if(s[i].b <= temp.e)
               {
                   cnt++;
                   s[i].stall = cnt;
                   que.push(s[i]);
               }
               else
               {
                   s[i].stall = temp.stall;
                   que.pop();
                   que.push(s[i]);
               }
           }
        }

        sort(s,s+N,cmp2);
        printf("%d\n",cnt);
        for(int i = 0;i < N;i++)
            printf("%d\n",s[i].stall);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值