【贪心】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;
}
标签:right,int,anss,Ybt,include,畜栏,贪心,left 来源: https://blog.csdn.net/qq_42937087/article/details/112121486