贪心算法基础之活动时间安排(二) 51nod 贪心教程

有若干个活动,第i个开始时间和结束时间是[Si,fi),活动之间不能交叠,要把活动都安排完,至少需要几个教室?

输入

第一行一个正整数n (n <= 10000)代表活动的个数。
第二行到第(n + 1)行包含n个开始时间和结束时间。
开始时间严格小于结束时间,并且时间都是非负整数,小于1000000000

输出

一行包含一个整数表示最少教室的个数。

输入示例

3
1 2
3 4
2 9

输出示例

2


解题思路一:


把所有的开始时间和结束时间按从小到大排序,


然后我们从最小的时间开始走,


遇到的开始时间就加一个会场,遇到结束时间就建一个会场。


一开始是0个会场,走到最后也一定是0个(开始时间和结束时间的数目相等)


那么在时间走的过程中,一定会经历会场数很多的状态,我们需要记录下最大的会场数,即答案


代码:

#include<stdio.h>
#include<algorithm>
using namespace std;
int main()
{
	int a[10000];//开始时间
	int b[10000];//结束时间
	int n,i,j;
	while(scanf("%d",&n)!=EOF)
	{
		for(int i=0;i<n;i++)
			scanf("%d%d",&a[i],&b[i]);
		sort(a,a+n);
		sort(b,b+n);
		i=j=0;
		int count=0;//实时会场数
		int ans=0;//答案 
		while(i<n&&j<n)//a,b两个数组同时在时间轴上走 
		{
			if(a[i]<b[j])
			{
				count++;
				i++;
			}
			if(ans<count)//这句对ans的更新一定要紧跟在count加了之后 
				ans=count;
			if(a[i]>b[j])
			{
				count--;
				j++;
			}
			if(a[i]==b[j])
			{
				i++;j++;
			}
		}
		//时间轴走完了开始时间或者结束时间,就可以得到最多的同时进行的活动的场数 
		printf("%d\n",ans);
	}
	return 0;
}






解题思路二:

建立一个时间轴,(像一维数轴一样即可),如图




把所有活动安排的时间段以线段的形式画在时间轴上,


某一时刻需要的教室数,其实就是那一刻的线段重合的数目。


所以,我们只要找出最多能重合多少线段。


代码:

#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
struct node{
	int b,e;
}a[100100];

bool cmp(node a,node b)
{
	return a.b<b.b;
} 
int main()
{
	int N;
	while(~scanf("%d",&N))
	{
		priority_queue<int, vector<int>, greater<int> > q; 
		//优先队列先出小的元素 
		for(int i=0;i<N;i++)
		{
			scanf("%d%d",&a[i].b,&a[i].e);
		}
		sort(a,a+N,cmp);//按开始时间从小到大排序。 
		
		q.push(a[0].e);//队列装已经进行了的活动的结束时间 
		int count =0;//记录下会场最多的数目 
		for(int i=1;i<N;i++)
		{
			while(!q.empty()&&q.top()<=a[i].b)//时间点过了的活动从队列里删除 
				q.pop();
			q.push(a[i].e);
			if(count<q.size())
				count=q.size();
		}
		printf("%d\n",count);
	}
	return 0;
}




解题思路一:

建立一个时间轴,(像一维数轴一样即可),把所有的活动时间按结束时间排序,


以线段的形式画在时间轴上,然后遍历所有活动。每加入一个活动,只需满足上一个占用着会场的活动结束了。


为什么要以结束时间排序呢?因为我们要尽量多的安排活动,当然希望下一个进来的活动能够成功安排进去,


那么就要求上一个活动尽量早结束。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪的期许

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值