1 条题解
-
0
1:把奶牛按照挤奶开始时间从前往后排序 2:为第一头奶牛分配畜栏 3:依次处理后面的每一头奶牛,处理第i头奶牛时候,考虑已分配畜栏中结束时间最早的畜栏x。 若畜栏结束时间<奶牛开始时间,则不用分配新的畜栏,i可以进入x,并修改畜栏结束时间为E(i) 若畜栏结束时间>=奶牛开始时间,则分配新的畜栏,E(i) 直到所有奶牛处理结束
贪心策略: 按奶牛的开始时间升序排序。 使用优先队列(小顶堆)维护每个畜栏的结束时间,每次选择最早结束的畜栏。 畜栏分配: 若最早结束的畜栏可用(结束时间早于当前奶牛的开始时间),则复用该畜栏。 否则,新开一个畜栏。 数据结构: Cow 结构体:存储奶牛的开始时间、结束时间和编号。 Stall 结构体:存储畜栏的结束时间和编号,使用优先队列维护。 原文链接:https://blog.csdn.net/weixin_45822638/article/details/105272109#include <iostream> #include <algorithm> #include <queue> #include <vector> using namespace std; struct Cow {//奶牛 int a, b; //挤奶区间起终点 int No; //编号 bool operator<(const Cow& c) const { return a < c.a;//按照开始时间从早到晚排序 } } cows[50100]; int pos[50100]; //pos[i]表示编号为i的奶牛去的畜栏编号 struct Stall {//畜栏 int end; //结束时间 int No; //编号 bool operator<(const Stall& s) const { return end > s.end;//按照畜栏的结束时间排序 } Stall(int e, int n) :end(e), No(n) { } }; int main() { int n; cin>>n; for (int i = 0; i < n; ++i) { cin>>cows[i].a>>cows[i].b; cows[i].No = i; } sort(cows, cows + n); int total = 0; priority_queue<Stall> pq;//畜栏的队列 for (int i = 0; i < n; ++i) { if (pq.empty()) {//如果畜栏为空的话,就是放入第一个畜栏 ++total; pq.push(Stall(cows[i].b, total));//并且新开一个畜栏,以放入当前奶牛的结束时间为畜栏的结束时间 pos[cows[i].No] = total; } else { Stall st = pq.top();//指向队列的顶端,即即将释放的畜栏 if (st.end < cows[i].a) { //端点也不能重合如果畜栏的结束时间早于奶牛的开始时间的话 pq.pop(); pos[cows[i].No] = st.No; pq.push(Stall(cows[i].b, st.No)); } else { //对应 if( st.end < cows[i].a //畜栏的结束时间晚于奶牛的开始时间,即队列中没有可以释放的畜栏,就新开一个畜栏放入奶牛 ++total; pq.push(Stall{cows[i].b,total });//畜栏结束时间设置为奶牛结束 pos[cows[i].No] = total; } } } cout << total << endl; for (int i = 0; i < n; ++i) cout << pos[i] << endl; return 0; }
- 1
信息
- ID
- 2191
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 2
- 上传者