Stall Reservations
luogu 2859
poj 3190
题目大意:
有n头牛,每头牛都有自己的挤奶时间,挤奶时间内每头牛用一个奶棚,现在问最少需要多少个奶棚
输入样例
5
1 10
2 4
3 6
5 8
4 7
输出样例
4
1
2
3
2
4
数据范围
1⩽N⩽50,0001 \leqslant N \leqslant 50,0001⩽N⩽50,000
1⩽A⩽B⩽1,000,0001 \leqslant A \leqslant B \leqslant 1,000,0001⩽A⩽B⩽1,000,000
解题思路:
直接贪心,当有位时就进去,否则开一个,但这样o(n2)o(n^2)o(n2)会TLETLETLE,所以我们用STL堆来求空的,使时间复杂度优化到o(nlogn)o(n\ log_n)o(n logn)
代码:
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,ans;
struct rec
{int s,bg,ed,num;
}a[50500];
bool operator <(const rec &x,const rec &y){return x.ed>y.ed;}//改为小根堆
bool cmp(rec x,rec y){return x.bg<y.bg;}
bool cmpp(rec x,rec y){return x.num<y.num;}
int main()
{scanf("%d",&n);for (int i=1;i<=n;++i){scanf("%d %d",&a[i].bg,&a[i].ed);a[i].num=i;}sort(a+1,a+1+n,cmp);priority_queue<rec>d;//定义堆a[1].s=1;d.push(a[1]);ans=1;for (int i=2;i<=n;++i){rec h=d.top();if (h.ed<a[i].bg)//看看是否重复{d.pop();a[i].s=h.s;//记录牛棚的编号d.push(a[i]);//入堆}else{a[i].s=++ans;//新建一个牛棚d.push(a[i]);}}sort(a+1,a+1+n,cmpp);//排序回原来的样子printf("%d\n",ans);for (int i=1;i<=n;++i)printf("%d\n",a[i].s);
}