挑战程序设计竞赛2.2习题:Stall Reservations POJ - 3190

Stall Reservations

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

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.

这道题是讲怎么把找到区间最大覆盖并且把每个牛的所在的机器也要一并求出。要是只求出最大覆盖数以及其区间我们可以设置一个diff数组用于存放该时间段与上一个时间段的差值,这样在加入一个时间段时只要修改起始时间的diff(起始时间比原来加一了,所以该加一)和结束后一个时间的diff(因为结束时间的覆盖数加一了,所以下一个与它的差值应该减一)即可,因为之间的时间差值并未发生变化。最后在O(n)遍历一边求得最大值即可。

但是本题不行,因为还要求出每头牛使用的机器号。那我们就采用贪心策略进行解决。

因为每次肯定是起始时间靠前的去找FJ取奶,所以我们排序要按照起始时间靠前的排列,每次FJ应当判断所有的机器中当前最早结束的结束时间是不是比要加进去的牛的起始时间早,因为如果最早结束都晚了,其他的肯定不可能,那么FJ就要再去买一台机器。如果可以呢?那我们就放到某台机器中去。由于在所有的机器中,能放下那头牛的机器(可能不止一台)集合实际上的有效时间都是一样的,只要能放,不管之前那台机器的结束时间最早还是不最早,其实都是没有影响的,因为能放的机器集合有效时段都是从本头牛的起始时间(因为之后的牛必大于等于这个起始时间,因为排序就这么排的)到所有牛里面的最晚结束时间,但是我们既然比较了最早结束且能放,那我们就用它咯!

于是乎我们得到这样解决问题的算法:我们建立一个优先队列(能插入时O(logn)排好序),找到我们要的当前最早结束的机器,然后将结束时间与当前想要挤奶的奶牛的起始时间进行比较,如果能放进去,那么那个奶牛使用的机器号就是那个最早结束的机器号,由于奶牛进去后该台机器的结束时间不再是以前的时间了,所以我们把第一的那台机器的时间pop掉,由于新加进去的奶牛的结束时间为该台机器新的结束时间,我们把奶牛放进队列,实际上也是把该台机器新的结束时间放进队列;如果不能放进去,那FJ就要买一台机器放进去,同样那台机器的结束时间就是那头牛的结束时间。由于新机器里面只有一头牛,该牛的结束时间为该机器的结束时间,若下次放第二头则第一头pop,第三头则第二头pop所以其实队列的元素个数也就是机器的数量(因为每台机器这样操作只能留一头,也就是最近加进来的那一头,之前的被pop了,新机器不会pop但是也是只有一头),所以队列的优先既是每台机器最近的奶牛的结束时间的最小值,也是每台机器结束时间的最小值。

AC代码(思路来源:https://blog.csdn.net/u014303647/article/details/38342603):

#include <stdio.h>
#include <queue>
#include <algorithm>
using namespace std;
struct Node{
    int s;
    int e;
    int i;
    friend bool operator <(Node x, Node y)
    {
        return x.e > y.e;
    }
}cows[50005];
bool cmp (Node x, Node y)
{
    return x.s < y.s;
}
int order[50005];
priority_queue<Node> pq;
int ans;
int main(void)
{
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; i++)
    {
        scanf("%d %d", &cows[i].s, &cows[i].e);
        cows[i].i = i;
    }
    sort(cows, cows + n, cmp);
    pq.push(cows[0]);
    ans = 1;
    order[cows[0].i] = 1;
    for(int i = 1; i < n; i++)
    {
        if(!pq.empty() && pq.top().e < cows[i].s)//能把A牛放在B机器中(A牛:新加牛,B机器:当前最早结束的机器)
        {
             order[cows[i].i] = order[pq.top().i];//新加入的牛A使用的机器号就是B,而B就是当前所有机器最早结束的牛的机器号
            pq.pop();//B原来的牛不能代表B的结束时间了,pop掉
        }
        else
        {
            ans++;//FJ买了新的机器
            order[cows[i].i] = ans;//新的机器号放的当然是新加入的牛
        }
        pq.push(cows[i]);//把牛(实际上是选中放这头牛的机器的结束时间)放入队列中
    }
    printf("%d\n", ans);
    for(int i = 0; i < n; i++)
        printf("%d\n", order[i]);
    while(!pq.empty())
        pq.pop();
    return 0;
}
        

原文地址:https://www.cnblogs.com/jacobfun/p/12200429.html

时间: 2024-10-04 21:28:22

挑战程序设计竞赛2.2习题:Stall Reservations POJ - 3190的相关文章

挑战程序设计竞赛2.2习题:Allowance POJ - 3040

Allowance As a reward for record milk production, Farmer John has decided to start paying Bessie the cow a small weekly allowance. FJ has a set of coins in N (1 <= N <= 20) different denominations, where each denomination of coin evenly divides the

Stall Reservations(POJ 3190 贪心+优先队列)

Stall Reservations Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4434   Accepted: 1588   Special Judge 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 in

Stall Reservations (poj 3190 贪心)

Language: Default Stall Reservations Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3394   Accepted: 1215   Special Judge Description Oh those picky N (1 <= N <= 50,000) cows! They are so picky that each one will only be milked over so

挑战程序设计竞赛2.3习题:Cheapest Palindrome POJ - 3280

Keeping track of all the cows can be a tricky task so Farmer John has installed a system to automate it. He has installed on each cow an electronic ID tag that the system will read as the cows pass by a scanner. Each ID tag's contents are currently a

挑战程序设计竞赛2.3习题:Making the Grade POJ - 3666

A straight dirt road connects two fields on FJ's farm, but it changes elevation more than FJ would like. His cows do not mind climbing up or down a single slope, but they are not fond of an alternating succession of hills and valleys. FJ would like t

挑战程序设计竞赛2.3习题:Cow Exhibition POJ - 2184

"Fat and docile, big and dumb, they look so stupid, they aren't muchfun..."- Cows with Guns by Dana Lyons The cows want to prove to the public that they are both smart and fun. In order to do this, Bessie has organized an exhibition that will be

挑战程序设计竞赛2.4习题:Moo University - Financial Aid POJ - 2010

Bessie noted that although humans have many universities they can attend, cows have none. To remedy this problem, she and her fellow cows formed a new university called The University of Wisconsin-Farmside,"Moo U" for short. Not wishing to admit

挑战程序设计竞赛2.6习题:X-factor Chains POJ - 3421

Given a positive integer X, an X-factor chain of length m is a sequence of integers, 1 = X0, X1, X2, …, Xm = X satisfying Xi < Xi+1 and Xi | Xi+1 where a | b means a perfectly divides into b. Now we are interested in the maximum length of X-factor ch

挑战程序设计竞赛3.1习题:Moo University - Financial Aid POJ - 2010

(原题见POJ2010) 这道题我之前采用了优先队列+预处理的方法求解(https://www.cnblogs.com/jacobfun/p/12244509.html),现在用二分的办法进行求解. 一开始我很纳闷,采用二分求解本题,如果二分的mid值不符合条件,按照二分右边界应该为mid - 1(我采用前闭后闭的二分),那么如果mid + xxx(xxx大于0)可以呢?(考虑mid不行是因为左边最小加起来大了,mid ~ mid + xxx中有极小值,使得mid + xxx的左边可以满足,那么