【贪心】Ybt_畜栏预定

题目大意

同一时间内,一个畜栏只能供一头牛使用。给出一些牛需要使用畜栏的时间段,让你求使用的最少畜栏数量与安排方案。

输入

第一行一个 n ,代表牛的数量
接下来 2 ~ n+1 行,每行两个数,代表这头牛使用畜栏的起始时间与结束时间。

输出

第一行一个数,代表最少畜栏数量。
接下来 2 ~ n+1 行,每行一个数,代表这头牛安排到第几个畜栏。


先按开始时间从小到大排序,时间相同的按结束时间从小到大排序。

假设我们已经安排了k头牛在畜栏内,对于要考虑的下一头牛:
1.它的开始时间比在畜栏内的牛最早结束时间早
冲突,新建一个畜栏。
2.它的开始时间比在畜栏内的牛最早结束时间晚
将它安排进已结束使用的畜栏。

在畜栏内的牛最早结束时间可以用堆维护。


代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
int n, ans, zz, x, y, Ans;
priority_queue <pair<int, int>, vector<pair<int, int> >, greater<pair<int ,int> > > q;  //小根堆
struct asdf{
    
    
	int left, right, id;
} a[50011];
struct sdfg{
    
    
	int id, wl;
} anss[50011];
bool cmp(asdf aa, asdf bb){
    
      //排序
	if(aa.left != bb.left) return aa.left < bb.left;
	return aa.right < bb.right;
}
int main(){
    
    
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i){
    
    
		scanf("%d%d", &a[i].left, &a[i].right);
		a[i].id = i;
	} 
	sort(a+1, a+1+n, cmp);
	
	for(int i = 1; i <= n; ++i)  //存围栏用的变量anss
	  anss[i].id = a[i].id;
	
	anss[1].wl = 1;
	Ans = 1; 
	q.push(make_pair(a[1].right, 1));  //(结束时间,畜栏序号)
	for(int i = 2; i <= n; ++i){
    
    
		int now = q.top().first;
		if(a[i].left <= now){
    
      //新建围栏
			++Ans;
			anss[i].wl = Ans;
			q.push(make_pair(a[i].right, Ans));
		}
		else{
    
      //丢入以前的围栏
			anss[i].wl = q.top().second;
			q.pop();
			q.push(make_pair(a[i].right, anss[i].wl));
		}
	}
	for(int i = 1; i <= n; ++i)  //还原顺序
	  a[anss[i].id].left = anss[i].wl;
	printf("%d\n", Ans);
	for(int i = 1; i <= n; ++i)  
	  printf("%d\n",a[i].left);
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/qq_42937087/article/details/112121486