51Nod:活动安排问题之二(贪心)
有若干个活动,第i个开始时间和结束时间是[Si,fi),同一个教室安排的活动之间不能交叠,求要安排所有活动,最少需要几个室?
第一行一个正整数n (n <= 10000)代表活动的个数。 第二行到第(n + 1)行包含n个开始时间和结束时间。 开始时间严格小于结束时间,并且时间都是非负整数,小于1000000000
一行包含一个整数表示最少教室的个数。
3 1 2 3 4 2 9
2
分析:能否按照之一问题的解法,每个教室安排尽可能多的活动,即按结束时间排序,再贪心选择不冲突的活动,安排一个教室之后,剩余的活动再分配一个教室,继续贪心选择……
教室1: A C
教室2: B
教室3: D
需要3个教室
策略: 按照开始时间排序优先安排活动,如果冲突,则加一个教室。
简单地理解一下,策略是这样,我们把活动按照开始时间有小到大的顺序排序。假设目前已经分配了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;
}
转载于:https://www.cnblogs.com/Friends-A/p/9309057.html
51Nod:活动安排问题之二(贪心)相关推荐
- 活动安排问题 动态规划、贪心算法C语言实现
问题描述 设有n个活动的集合E={1,2,-,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源.每个活动i都有一个要求使用该资源的起始时间si和一个结束 ...
- C语言:用贪心策略计算活动安排问题的最优解
文章目录 前言 一.活动安排问题 二.解题思路 三.代码实现 总结 前言 关于这个活动安排问题的解题思路我第一遍是真的没看懂,所以我就直接看代码了,没想到啊,过一遍代码就直接理解了,真神奇!所以啊,如 ...
- C++编程笔记:贪心算法实现活动安排问题
问题描述: 设有n个活动的集合E={1,2,-,n},其中,每个活动都要求使用同一资源,而在同一时间内只有一个活动能使用这一资源.每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi,且s ...
- 活动安排--贪心算法C语言实现
一.前言 大三下的算法设计分析课程.每周必备二道算法题.头疼.自己写的,大家看看就行.题目,我就截图 ,懒得赋文字了. 二.内容 代码: #include<stdio.h> typedef ...
- 【算法设计与分析】活动安排问题(动态规划和贪心算法)
一.活动选择问题描述 假设我们存在这样一个活动集合S={a1,a2,a3,a4,...,an},其中每一个活动ai都有一个开始时间si和结束时间fi保证(0≤si<fi),活动ai进行时,那么它 ...
- 基于贪心算法的活动安排问题
一.问题的描述 学校的小礼堂每天都会有许多活动,有时间这些活动的计划时间会发生冲突,需要选择出一些活动进行举办.小刘的工作就是安排学校小礼堂的活动,每个时间最多安排一个活动. 现在小刘有一些活动计划的 ...
- 活动安排问题--贪心算法
活动安排问题就是要在所给的活动集合中选出最大的相容活动子集合,是可以用贪心算法有效求解的很好例子.该问题要求高效地安排一系列争用某一公共资源的活动.贪心算法提供了一个简单.漂亮的方法使得尽可能多的活动 ...
- 贪心算法-02活动安排问题
活动安排问题 简介 活动安排问题是需要共享公共资源的一系列活动的高效安排问题,以在限定的资源前提下尽可能多地安排活动.一般,算法题中给出开始结束时间的活动序列都可以使用这种贪心思路. 问题描述 有若干 ...
- 贪心算法之 活动安排(Java代码实现)
活动安排问题 – 资源争夺 问题描述 设有 n 个活动的集合 A = {1, 2, - , n}, 其中每个活动都要求使用同一资源,而在同一时间段内只有一个活动能使用资源 要求高效安排一系列争用公共资 ...
最新文章
- 密码学基础知识(六)Hash函数与消息认证
- 处理字符串_1_生成自增值
- MapReduce案例-wordcount-Reduce阶段代码
- 【POI word】使用POI实现对Word的读取以及生成
- leetcode 480. 滑动窗口中位数(堆+滑动窗口)
- MySQL Cluster 用户权限共享 (各sql节点同步)
- 计算机内存比外存容量大吗,内存容量一般比外存容量大吗
- 基于WF的意见征集6(浅析)
- 提高MyEclipse启动速度
- excel两列数据绘制单折线图
- 个性化hexo博客,添加评论系统,分享,友情链接功能
- (转)用Wineskin 让Windows 的程序在Mac 上运行
- 主数据管理(MDM)的成熟度
- 《华为研发》读书笔记与读后感范文3300字
- 布局 - 收藏集 - 掘金
- git目录下object文件过大清理
- Win10系统自带的虚拟机怎么打开教学
- 医疗器械软件 软件生存周期过程
- DNS异步请求池原理与实现
- 【C++】-命名空间的概念及使用