畜栏预定
题目链接: 链接
题目大意:
有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;
}