有若干个活动,第i个开始时间和结束时间是[Si,fi),同一个教室安排的活动之间不能交叠,求要安排所有活动,最少需要几个教室?
Input
第一行一个正整数n (n <= 10000)代表活动的个数。 第二行到第(n + 1)行包含n个开始时间和结束时间。 开始时间严格小于结束时间,并且时间都是非负整数,小于1000000000
Output
一行包含一个整数表示最少教室的个数。
Input示例
3 1 2 3 4 2 9
Output示例
2
思路:
1、很经典的贪心题,先按结束时间从小到大排序,再模拟一下让每个教室安排尽可能多的活动即可。自己写的暴力代码O(n2),竟然没有TLE,很意外~
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int Max_v=1e4+10;
int n;
struct edge{
int s,t;
bool operator<(const edge &e){
return s<e.s;
}
}e[Max_v];
int a[Max_v];
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d%d",&e[i].s,&e[i].t);
}
sort(e,e+n);
int k=0,i,j;
memset(a,0,sizeof(a));
for(i=0;i<n;i++){
for(j=0;j<k;j++){
if(e[i].s>=a[j]){
a[j]=e[i].t;break;
}
}
if(j==k){a[j]=e[i].t;k++;}
}
printf("%d\n",k);
return 0;
}
2、维护一个结束时间的最小堆,每次比较开始时间和堆中最小时间的大小,如果比它大就放入堆中并且时间就要变成当前任务的结束时间,否则就要新开一个教室.并且把结束时间加入堆中,复杂度O(nlogn)。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int Max_v=1e4+10;
int n;
struct edge{
int s,t;
bool operator<(const edge &e){
return s<e.s;
}
}e[Max_v];
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d%d",&e[i].s,&e[i].t);
}
sort(e,e+n);
priority_queue<int,vector<int>,greater<int> >que;
que.push(e[0].t);
int k=1;
for(int i=1;i<n;i++){
int p=que.top();
if(e[i].s>=p){
que.pop();que.push(e[i].t);
}
else {
k++;que.push(e[i].t);
}
}
printf("%d\n",k);
return 0;
}