活动安排问题:区间贪心

题目描述

假设某社团某一天要组织𝑛个活动𝐸 = {1, 2, ⋯ , 𝑛} ,其中每个活动都要求使用同一礼堂,而且 在同一时间内只有一个活动能使用这个礼堂。每个活动𝑖都有一个要求使用礼堂的起始时间𝑠𝑖 和结束时间 𝑓𝑖,且有𝑠𝑖 < 𝑓𝑖 。如果选择了活动𝑖,则它在半开时间区间[𝑠𝑖 , 𝑓𝑖) 内占用资源。若 区间[𝒔𝒊, 𝒇𝒊) 与区间[𝒔𝒋, 𝒇𝒋) 不相交,则称活动𝐢与活动𝐣是相容的。现在给定𝑛个活动的开始时间和结束时间,请设计一个活动安排方案,使得安排的相容活动数目最多。

输入

第一行是一个整数n;第二行到第n+1行都有两个整数,分别是活动i的起始时间和结束时间

输出

输出满足条件的活动数目的最大值。

Input

11
1 4
0 6
3 5
3 8
5 7
5 9
6 10
8 11
8 12
2 13
12 14

Output

4

思路

假设选取了第一个活动,则第一个活动的结束时间会影响下一个活动的起始时间,怎么才会使满足条件的数目达到最大呢?我们让结束时间小的活动排在最前面,然后依次往后遍历,如果当前活动的结束时间早于下一个活动的起始时间,则这个活动满足条件,这样就达到最优的效果。

代码
#include<stdio.h>
#define MaxSize 1000
typedef struct Node{
	int start,end;
}node;
void swap(Node *a,Node *b){
	Node temp=*a;
	*a=*b;
	*b=temp;
}
void BubbleSort(int n,node *arr){
	for(int i=1;i<n-1;i++)//利用冒泡排序 
		for(int j=0;j<n-i;j++)
			if(arr[j+1].end<arr[j].end)
				swap(&arr[j+1],&arr[j]); 
}
int	solve(int n,node *arr,node *temp){
	BubbleSort(n,arr);//当然这个题跟排序的稳定性无关,所以可以采用其他的排序,如果活动数目过大还可以采用快排 
	int select=0;//选取第一个活动 
	temp[0]=arr[select];//选取第一个活动 
	int cnt=1;//选取活动数目 
	for(int i=1;i<n;i++){
		if(arr[select].end<=arr[i].start){//如果满足当前活动的开始时间在前一个活动的结束时间之后 
			temp[cnt++]=arr[i];//满足选取条件 
			select=i;//改变选取当前的最后一个活动
		}
	}
	return cnt;
}
int main(){
	int n;
	puts("输入活动数目n");
	scanf("%d",&n);
	puts("依次输入活动i的起始时间和结束时间");
	node arr[MaxSize],temp[MaxSize];//arr为输入的活动,temp为选取的活动 
	for(int i=0;i<n;i++)	scanf("%d%d",&arr[i].start,&arr[i].end);
	int num=solve(n,arr,temp);
	printf("选取了%d个活动\n",num);
	printf("这%d个活动分别是\n",num); 
	for(int i=0;i<num;i++)
		printf("start=%d end=%d\n",temp[i].start,temp[i].end);
	return 0;
}
/*
11
1 4
0 6
3 5
3 8
5 7
5 9
6 10
8 11
8 12
2 13
12 14
*/
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

星空皓月

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

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

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

打赏作者

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

抵扣说明:

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

余额充值