《算法竞赛进阶指南》贪心篇 畜栏预定 (贪心+堆处理)

畜栏预定

题目链接: 链接

题目大意:

有n头牛在吃k片草,一片草只能一个牛同时吃,牛吃饭有一个时间区间,在这个时间里,别的牛只

能去吃别的草,问最少要准备几片草。

思路:

区间问题的贪心,首先把牛吃饭区间按照左端点从小到大排序一下,然后建立某片草没牛吃空

闲的小根堆,如果不符合条件的话,建立新的草。

如图:
在这里插入图片描述

Code:

#pragma GCC optimiza(2) 
#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long int ll;
const int maxn = 70000;


pair<pair<int,int>,int> cows[maxn]; 
int id[maxn];

int main(){
    int n;
    cin>>n;
	
	for(int i=1;i<=n;i++){
		cin>>cows[i].first.first>>cows[i].first.second;  //牛吃饭的区间
		cows[i].second=i; //记录第几个牛
	}
	sort(cows+1,cows+1+n);
	
	priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > head; //建立小根堆
	
	for(int i=1;i<=n;i++){
		if(head.empty()||head.top().first>=cows[i].first.first){  //建立新的草地
			pair<int,int> stall= {cows[i].first.second,head.size()};
			id[cows[i].second]=stall.second+1;
			head.push(stall);
		}
		else{                                       //把此牛安排到空闲的草地吃
			pair<int,int> stall=head.top();
			head.pop();
			stall.first=cows[i].first.second;
			id[cows[i].second]=stall.second+1;
			head.push(stall);
		}
	}
	
	cout<<head.size()<<endl;
	for(int i=1;i<=n;i++) cout<<id[i]<<endl;
	return 0;
}


猜你喜欢

转载自blog.csdn.net/weixin_43872264/article/details/107537941