有若干个活动,第i个开始时间和结束时间是[Si,fi),同一个教室安排的活动之间不能交叠,求要安排所有活动,最少需要几个室?

输入
第一行一个正整数n (n <= 10000)代表活动的个数。
第二行到第(n + 1)行包含n个开始时间和结束时间。
开始时间严格小于结束时间,并且时间都是非负整数,小于1000000000
输出
一行包含一个整数表示最少教室的个数。
输入示例
3
1 2
3 4
2 9
输出示例
2
有若干个活动,第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在另外一个教室,两个教室就够了。
所以之前的贪心策略解决不了这个问题。
怎么办?之前的策略是用一个教室找所有它能安排下的活动,即用教室找活动,我们能不能用活动找教室呢?

策略: 按照开始时间排序优先安排活动,如果冲突,则加一个教室。
简单地理解一下,策略是这样,我们把活动按照开始时间有小到大的顺序排序。假设目前已经分配了k个教室(显然k初始等于0),对于当前这个活动,
(1) 如果它能安排在k个教室里的某一个,则把它安排在其中的任何一个教室里,k不变。
(2) 否则它和每个教室里的活动都冲突,则增加一个教室,安排这个活动。

这个策略是最优么?

我们想像一下k增加1的过程: 因为我们是按照开始时间排序的,意味着当前考虑的这个活动开始的时候,k个教室里都有活动没结束(因为如果有一个教室的活动结束了,我们就可以安排这个活动进入那个教室而不冲突,从而不用增加k)。这就意味着在这个活动开始的时间点,算上目前考虑的这个活动,有(k + 1)个活动正在进行,同一时刻有(k + 1)个活动在进行,无论我们如何安排教室,都至少需要(k + 1)个教室。因为每个教室里不能同时进行两个活动。而我们的策略恰好需要(k + 1)个教室,所以是最优的。

这个策略也告诉我们,如果从时间轴上“宏观”考虑这个问题。考虑每个时间点同时进行的活动个数,作为这个时间点的厚度(把活动开始和结束时间想像成线段,那么每个时间点有多少条线段覆盖它,可以简单理解为“厚度”),我们至少需要最大厚度那么多个教室——因为那时恰好有最大厚度那么多个活动同时进行,而我们这个贪心策略恰好给了我们一个用最大厚度那么多个教室安排全部活动的一个方案。

如果只需要教室的个数,我们可以把所有开始时间和结束时间排序,遇到开始时间就把厚度加1,遇到结束时间就把厚度减1,显然最初始和最后结束时的厚度是0,在一系列厚度变化的过程中,峰值(最大值)就是最多同时进行的活动数,也是我们至少需要的教室数。

方法一:就是51Nod里面讲解的方法(上面的绿色部分),不需要使用结构体

AC代码:

#include<bits/stdc++.h>
#define x 10010
using namespace std;
int main()
{
int s[x],e[x];
int n,i,k;
scanf("%d",&n);
for(i=0;i<n;i++) scanf("%d%d",&s[i],&e[i]);
sort(s,s+n);
sort(e,e+n);
int sum=0;
for(i=0,k=0;i<n;i++)
{
if(s[i]<e[k]) sum++;
else k++;
}
printf("%d\n",sum);
return 0;
}

方法二:使用结构体(这种方法思路和方法一基本上一样,但是时间复杂度大了好多)

//还有别的复杂度小的方法,但是水平有限,百度到的方法不(kan)会(bu)用(dong)

AC代码:

#include<bits/stdc++.h>
#define x 10100
using namespace std;
struct wzy{
int start,end;
}p[x];
int cmp(wzy u,wzy v)//对时间进行排序,
{
if(u.start!=v.start) return u.start<v.start;//开始时间不同,把先开始的放前面
else return u.end<v.end;//开始时间相同,把先结束的放前面
}
int main()
{
int n,i,j,k,sum;
scanf("%d",&n);
for(i=0;i<n;i++) scanf("%d%d",&p[i].start,&p[i].end);
sort(p,p+n,cmp);
for(sum=0,i=0;i<n;i++)
{
k=0;
for(j=i;j>=0;j--)//每次都要从i往前推一边,找出来在第i组数据的时候需要几个房间
{ //这个思路和方法一大致相同,都是找结束时间与开始时间的关系。从j=i开始是因为无论怎样都至少需要一个房间
if(p[j].end>p[i].start)
k++;
}
sum=sum>k?sum:k;//取最大值
}
printf("%d\n",sum);
return 0;
}

51Nod:活动安排问题之二(贪心)的更多相关文章

  1. C语言 活动安排问题之二

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

  2. 51Nod 活动安排问题(排序+优先队列)

    有若干个活动,第i个开始时间和结束时间是[Si,fi),同一个教室安排的活动之间不能交叠,求要安排所有活动,最少需要几个教室? Input 第一行一个正整数n (n <= 10000)代表活动的 ...

  3. 忙碌的Nova君 (活动安排问题、贪心算法)

    题目描述 理论上,Nova君是个大闲人,但每天还是有一大堆事要干,大作业啦,创新杯啦,游戏啦,出题坑人啦,balabala......然而精力有限,Nova君同一时间只能做一件事,并不能一心二用.假设 ...

  4. [C++] 贪心算法之活动安排、背包问题

    一.贪心算法的基本思想 在求解过程中,依据某种贪心标准,从问题的初始状态出发,直接去求每一步的最优解,通过若干次的贪心选择,最终得出整个问题的最优解. 从贪心算法的定义可以看出,贪心算法不是从整体上考 ...

  5. 贪心算法求解活动安排<算法分析>

    一.实验内容及要求 1.要求按贪心算法原理求解问题: 2.要求手工输入s[10]及f[10],其中注意自己判断s[i]<f[i]: 3.要求显示所有活动及最优活动安排的i事件列表.二.实验步骤  ...

  6. 51Nod 1428 活动安排问题

    51Nod   1428  活动安排问题 Link: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1428 1428 活 ...

  7. hdu 2037简单贪心--活动安排问题

    活动安排问题就是要在所给的活动集合中选出最大的相容活动子集合,是可以用贪心算法有效求解的很好例子.该问题要求高效地安排一系列争用某一公共资源的活动.贪心算法提供了一个简单.漂亮的方法使得尽可能多的活动 ...

  8. hdu2037今年暑假不AC(贪心,活动安排问题)

    今年暑假不AC Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submi ...

  9. A - 活动安排问题(贪心)

    A - 活动安排问题 有若干个活动,第i个开始时间和结束时间是[Si,fi),同一个教室安排的活动之间不能交叠,求要安排所有活动,最少需要几个教室?  Input第一行一个正整数n (n <= ...

随机推荐

  1. Vue项目骨架屏注入实践

    相比于早些年前后端代码紧密耦合.后端工程师还得写前端代码的时代,如今已发展到前后端分离,这种开发方式大大提升了前后端项目的可维护性与开发效率,让前后端工程师关注于自己的主业.然而在带来便利的同时,也带 ...

  2. C#一套简单的单例系统

    单例基类 public class CSingletonBase<TYPE> { public static TYPE Singleton { get { return m_singlet ...

  3. mysql数据库切分

    一.数据的垂直切分概念:数据的垂直切分,也可以称之为纵向切分.将不同的表分散到不同的数据库主机中.一个应用系统,总体功能肯定是由很多个功能模块所组成的,而每一个功能模块所需要的数据对应到数据库中就是一 ...

  4. LeetCode--171--Excel表列序号

    问题描述: 给定一个Excel表格中的列名称,返回其相应的列序号. 例如, A -> 1 B -> 2 C -> 3 ... Z -> 26 AA -> 27 AB -& ...

  5. 41 MYSQL 索引和慢查询优化

    一 .索引mysql 索引 b+tree 本质:通过不断地缩小想要获取数据的范围来筛选出最终想要的结果,同时把随机的事件变成顺序的事件,也就是说,有了这种索引机制,我们可以总是用同一种查找方式来锁定数 ...

  6. POJ-2689 Prime Distance (两重筛素数,区间平移)

    Prime Distance Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13961   Accepted: 3725 D ...

  7. HDU-1232 畅通工程 (并查集、判断图中树的棵数)

    Description 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相 ...

  8. js判断数组,对象是否存在某一未知元素

    1.对象 var obj = { aa:'1111', bb:'2222', cc: '3333' }; var str='aa'; if(str in obj){ console.log(obj[s ...

  9. mysql 基本语法学习1(数据库、数据表、数据列的操作)

    今天学习了一下mysql语法,并记录下来 1.mysql的数据库操作 /***1.操作数据库的语法 ***/ -- 1)显示所有数据库 -- show databases; -- 2)创建数据库 -- ...

  10. linux kernel swap daemon

    The name swap daemon is a bit of a misnomer as the daemon does more than just swap modified pages ou ...