分配畜栏
有n头牛(1<=n<=50000)要挤奶。给定每头牛挤奶的时间区间[A,B](1<=A<=B<=1000000,A,B为整数)。
牛需要呆畜栏里才能挤奶。一个畜栏同一时间只能容纳一头牛。
问至少需要多少个畜栏,才能完成全部挤奶工作,以及每头牛都放在哪个畜栏里
去同一个畜栏的两头牛,它们挤奶时间区间哪怕只在端点重合也是不可以的。
解题思路
先对所有奶牛开始时间排序
然后新开辟一个畜栏(再怎么样至少也有一个畜栏)
每一个畜栏就是一个优先队列,按照结束时间(会场安排、看电影的道理)从小到大排序
判断奶牛属于哪一个畜栏就是看这个奶牛的开始时间与前几个已经开辟完的畜栏的结束时间比,如果开始时间比结束时间段早,那就再分配新畜栏。
如果畜栏队列为空,我们就给它直接分配一个畜栏,将总共的畜栏序号++,然后把这头奶牛所放入的畜栏序号,就是当今的畜栏总号,填入pos数组,下标是奶牛的编号。
我们修改这个畜栏的结束时间,改成奶牛挤奶的结束时间,畜栏的序号也改成总的畜栏序号,之后压入优先队列。
如果畜栏队列不为空,就说明此时已经分配了畜栏,如果此时最早结束使用的畜栏,它的结束时间早于这头奶牛挤奶的开始时间,那我们就可以把这头奶牛放入这头畜栏。
我们把这个畜栏弹出优先队列,因为下一次压入之后的结束时间就改变了。
我们修改这个畜栏的结束时间为奶牛挤奶的结束时间,畜栏的序号不变。奶牛 i 的pos数组对应的位置修改成畜栏的序号,将畜栏压入优先队列。
如果最早结束的都不能满足的话,我们就重新给它分配一个畜栏,重复之前的队列为空的流程。
代码如下:
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;
struct Cow {
int start, end; //挤奶区间起终点
int num; //编号
bool operator < (const Cow& b)const {
return start < b.start;
}
}cow[50050]; //存放的奶牛
int pos[50050]; //pos[i]表示编号为i的奶牛的畜栏编号
struct Stall {
int end; //结束时间
int num;
bool operator < (const Stall& b)const {
return end > b.end;
}
Stall(int a, int b) :end(a), num(b) {}
};
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d%d", &cow[i].start, &cow[i].end);
cow[i].num = i;
}
sort(cow, cow + n);
int total = 0;
priority_queue<Stall>pq;
for (int i = 0; i < n; i++) {
if (pq.empty()) {
total++;
pos[cow[i].num] = total;
pq.push(Stall(cow[i].end, total));
}
else {
Stall st = pq.top();//结束时间最早的畜栏
if (st.end < cow[i].start) { //端点不能重合
pq.pop();
pos[cow[i].num] = st.num;
pq.push(Stall(cow[i].end, st.num));
}
else {
total++;
pos[cow[i].num] = total;
pq.push(Stall(cow[i].end, total));
}
}
}
printf("%d\n", total);
for (int i = 0; i < n; i++) {
printf("%d\n", pos[i]);
}
return 0;
}
大数据201 tyx
1260

被折叠的 条评论
为什么被折叠?



