Stall Reservations POJ - 3190(贪到优先队列家里了)

这里有N只 (1 <= N <= 50,000) 挑剔的奶牛! 他们如此挑剔以致于必须在[A,B ]的时间内产奶(1 <= A <= B <= 1,000,000)当然, FJ必须为他们创造一个决定挤奶时间的系统.当然,没有牛想与其他奶牛分享这一时光

帮助FJ做以下事:

  • 使每只牛都有专属时间的最小牛棚数
  • 每只牛在哪个牛棚

也许有很多可行解。输出一种即可,采用SPJ

Input

第一行一个数字 N

第 2..N+1行: 第 i+1行 描述了i号奶牛挤奶的起止时间

Output

第一行:牛棚最小数量

Lines 2..N+1: 第 i+1行 描述了i奶牛被安排的牛棚

Sample Input

5
1 10
2 4
3 6
5 8
4 7

Sample Output

4
1
2
3
2
4

Hint

样例解释:

这里是一种图示

Time     1  2  3  4  5  6  7  8  9 10

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

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

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

Stall 4 .. .. .. c5>>>>>>>>> .. .. ..

其他的也是可能的

一看题目,完全不知道怎么做,这个好像是个区间不相交贪心,(第一次见,没做过啥题的弱菜)。这道题目就是每个牛有个挤奶的时间,并且还得一个一个的排队,让我们求最小的挤奶机器(一个牛使用时,别的牛不能用)。我们可以这样想,不相交就是后面一个时间段的起始时间大于前面一个的结束时间(在按贪心策略排好序的前提下)。怎么排序呢,先开始挤奶的先上,如果起始时间一样,就按照时间段短的先排序(这里不排结束时间也一样,毕竟不影响相交)。这个是在一个结构体数组中排好序。但是要完成上面那个操作(按照那个结束时间),这时我们还要进行排序操作,来排结束时间(毕竟先结束的,赶快来下一个不相交时间段的牛,一个牛占的时间越长,其他牛的机会就会越少,所以先结束的先处理)。这个就是策略(有点乱)。

需要用到优先队列和结构体数组排序。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=60000;
int n,use[maxn];
struct Node
{
    int l;
    int r;
    int pos;
   bool operator <(const Node &a)const 
    {
		if(r==a.r)
		    return l>a.l;
		return r>a.r;
    }
}a[maxn];
priority_queue<Node> q;
bool cmp(Node a,Node b)
{
    if(a.l==b.l)
	return a.r<b.r;
    return a.l<b.l;
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
	for(int i=0;i<n;i++)
	{
	    scanf("%d%d",&a[i].l,&a[i].r);
	    a[i].pos=i;
	}
	sort(a,a+n,cmp);
	q.push(a[0]);
	int ans=1;
	use[a[0].pos]=1;
	for(int i=1;i<n;i++)
	{
	    if(!q.empty()&&q.top().r<a[i].l)
	    {
			use[a[i].pos]=use[q.top().pos];	
			q.pop();
	    }
	    else
	    {
			ans++;
			use[a[i].pos]=ans;
	    }
   		 q.push(a[i]);
	}
	printf("%d\n",ans);
	for(int i=0;i<n;i++)
	    printf("%d\n",use[i]);
	while(!q.empty())
	    q.pop();
    }
    return 0;
}	

因为最后要输出第i头牛在哪个机器处挤奶,我们需要多来一个数组(下标就是第几个牛)装的是几号挤奶机器,光有这个是不够的,优先队列里面还要有个元素来记录是几号牛。下面看看这个怎么代码实现怎么贪心的。

for(int i=1;i<n;i++)
	{
	    if(!q.empty()&&q.top().r<a[i].l)
	    {
			use[a[i].pos]=use[q.top().pos];	
			q.pop();
	    }
	    else
	    {
			ans++;
			use[a[i].pos]=ans;
	    }
   		 q.push(a[i]);
	}

先将最先挤奶的牛装进优先队列,再来下一个牛,如果不相交,就把之前的那个元素pop掉(因为它已经没用了,来了一个新的);如果相交的话,就不管之前的那个元素。每次都要装进一个数组(第几头牛使用哪个机器)。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值