51Nod 活动安排问题之二(贪心)

http://www.51nod.com/tutorial/course.html#!courseId=21&isCurrent=1

活动安排问题之二

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

分析:能否按照之一问题的解法,每个教室安排尽可能多的活动,即按结束时间排序,再贪心选择不冲突的活动,安排一个教室之后,剩余的活动再分配一个教室,继续贪心选择……

反例: A:[1,2)  B:[1,4) C:[5,6) D:[3,7)

已经按结束时间排好顺序,我们会选择
教室1: A C
教室2:  B
教室3:  D
需要3个教室。
但是如果换一种安排方法,我们可以安排AD在一个教室,而BC在另外一个教室,两个教室就够了。

所以之前的贪心策略解决不了这个问题。
最后,我们来提供输入输出数据,由你来写一段程序,实现这个算法,只有写出了正确的程序,才能继续后面的课程。

输入

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

输出

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

输入示例

3
1 2
3 4
2 9

输出示例

2

请选取你熟悉的语言,并在下面的代码框中完成你的程序,注意数据范围,最终结果会造成Int32溢出,这样会输出错误的答案。
不同语言如何处理输入输出,请查看下面的语言说明。


AC Code:

#include<stdio.h>
#include<cstring>
#include<algorithm>
#define AC main()
using namespace std;
typedef __int64 LL;
const int MYDD = 1103 + 1e4;

LL B[MYDD];//BeginTime
LL E[MYDD];//EndTime

int AC {
	int n;
	scanf("%d", &n);
	for(int j = 0; j < n; j++) {
		scanf("%I64d %I64d", &B[j], &E[j]);
	}
	sort(B, B + n);
	sort(E, E + n);
	int Next = 0, Answer = 0, sum = 0 ;
	for(int j = 0; j < n; j++) {
		if(B[j] < E[Next]) {/*下一场的结束时间晚*/
			Answer++;
		} else {
			Next++;/*当前教室仍然能够安排活动*/
		}
	}
	printf("%d\n", Answer);
	return 0;
}


WA Code:

#include<stdio.h>
#include<cstring>
#include<algorithm>
#define AC main()
using namespace std;
typedef __int64 ll;
const int MYDD = 1103 + 1e4;

struct Activity {
	ll str;//BeginTime
	ll end;//EndTime
} act[MYDD];
bool cmp(Activity a, Activity b) {
	if(a.str != b.str)
		return a.str < b.str;
	return a.end < b.end;
}

int AC {
	int n;
	scanf("%d", &n);
	for(int j = 0; j < n; j++) {
		scanf("%I64d %I64d", &act[j].str, &act[j].end);
	}
	sort(act, act + n, cmp);
	int Next = 0, Answer = 0, sum = 0 ;
	for(int j = 0; j < n; j++) {
		if(act[j].str < act[Next].end) {
			Answer++;
		} else {
			Next++;
		}
	}
	printf("%d\n",Answer);
	return 0;
}

 





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值