当前位置: 首页 > news >正文

贪心算法之会议安排问题

一、问题本质与核心目标

1. 问题定义

会议安排问题是经典的活动选择类优化问题,核心要素与目标如下:

  • 输入条件:给定一组会议(每个会议包含「开始时间」「结束时间」和「会议编号」三个属性),所有会议共用一个会场。
  • 核心规则:会场同一时间只能举办一个会议,即会议时间不能重叠。
  • 优化目标:在满足时间不重叠的前提下,最大化会场可安排的会议数量。

2. 与分数背包问题的关键差异

对比维度

会议安排问题

分数背包问题

问题核心

时间资源的无重叠分配

容量资源的价值最大化利用

贪心策略依据

会议结束时间

物品单位价值

选择规则

会议不可分割,要么全安排要么不安排

物品可分割,支持部分装入

二、算法核心:贪心策略的原理与合理性

1. 贪心策略的核心逻辑

        解决会议安排问题的贪心策略可概括为:优先选择「结束时间最早」的会议,若结束时间相同,则优先选择「开始时间最晚」的会议。

        选择结束时间最早的会议,能最大限度地节省时间资源,为后续安排更多会议留出充足时间;而结束时间相同时选开始时间最晚的会议,可进一步减少对后续时间的占用,降低时间浪费。

2. 策略合理性证明

该策略能确保得到最优解,核心原因有两点:

  • 早结束的会议能释放时间资源,让后续有更多机会安排其他会议,所以要避免因选择晚结束的会议导致大量时间被占用,而错失安排更多会议的可能。
  • 当会议结束时间相同时,开始时间晚的会议占用时间更短(例如 A 会议 9:00 - 10:00,B 会议 9:30 - 10:00,B 会议开始时间更晚,所占用时间更短),能进一步优化时间利用效率,不会额外消耗过多时间资源。

三、数据结构设计与关键变量

1. 核心数据结构:会议结构体

通过结构体封装会议的三个关键属性,便于统一存储和处理:

struct Meeting {int start; // 会议开始时间int end; // 会议结束时间int id; // 会议编号
} meetings[10005]; // 存储所有会议的数组

2. 关键变量说明

  • meetings[10005]:存储所有会议的数组,最大可容纳 10005 个会议,满足中等规模会议安排需求。
  • n:用户输入的实际会议数量(需小于等于 10005)。
  • count:统计可安排的会议总数,初始值为 1(默认先安排排序后第一个会议,即最早结束的会议)。
  • lastEnd:记录上一个已安排会议的结束时间,初始值为排序后第一个会议的结束时间,用于判断后续会议是否可安排(后续会议开始时间需 ≥ 该值)。

四、核心算法实现

1. 第一步:会议排序函数

        需先对所有会议按「结束时间升序」排序,结束时间相同时按「开始时间降序」排序,为后续贪心选择奠定基础,排序函数作为 sort 函数的比较器使用:

// 按结束时间升序排序,结束时间相同则按开始时间降序排序
bool cmp(const Meeting& a, const Meeting& b) {if (a.end == b.end) { // 结束时间相同的情况return a.start > b.start; // 开始时间大的排在前面}return a.end < b.end; // 结束时间不同时,结束时间小的排在前面
}
  • 排序后,会议列表的优先级顺序为:结束时间从早到晚,结束时间相同则开始时间从晚到早,确保后续遍历能优先处理最利于节省时间的会议。

2. 第二步:贪心选择算法(maxMeetings 函数)

该函数是核心计算模块,实现会议的选择与数量统计,具体逻辑如下:

// 计算最大可安排会议数,参数 n 为会议总数量
int maxMeetings(int n) {if (n == 0) {// 边界条件:无会议时,可安排数量为 0return 0; }sort(meetings, meetings + n, cmp); // 调用排序函数,对会议进行排序int count = 1; // 初始化可安排会议数为 1,默认安排第一个会议int lastEnd = meetings[0].end; // 记录第一个会议的结束时间,作为初始参考值// 遍历排序后的会议数组for (int i = 1; i < n; ++i) {// 若当前会议开始时间≥上一个会议结束时间,说明时间不重叠,可安排if (meetings[i].start >= lastEnd) {++count; // 可安排会议数加 1lastEnd = meetings[i].end; // 更新上一个会议的结束时间为当前会议的结束时间}}return count; // 返回最大可安排会议数
}

五、完整流程与示例分析

1. 完整执行流程

整个问题的解决流程分为「输入 → 处理 → 输出」三阶段,逻辑清晰:

1. 输入阶段
  • 用户输入会议数量n(如输入 “4”,代表有 4 个会议)
  • 依次输入每个会议的「开始时间」和「结束时间」(如输入 “8 10” “9 11” “10 12” “11 13”)
  • 自动为每个会议分配编号(从 1 开始,第一个会议编号为 1,第二个为 2,以此类推)
2. 处理阶段
  • 调用 sort(meetings, meetings + n, cmp),按规则对会议排序。
  • 调用 maxMeetings(n),计算最大可安排会议数。
3. 输出阶段

打印最终结果(如 “最多可安排的会议数量: 2”)。

2. 示例分步解析

以输入 “4;8 10;9 11;10 12;11 13” 为例,详细拆解处理过程:

  • 步骤 1:排序后会议顺序

        会议 1(start = 8,end = 10,id = 1)→

        会议 2(start = 9,end = 11,id = 2)→

        会议 3(start = 10,end = 12,id = 3)→

        会议 4(start = 11,end = 13,id = 4)

(按结束时间升序排序,结束时间均不同,无需按开始时间二次排序)。

  • 步骤 2:依次判断并安排会议
  1. 初始安排会议 1:count = 1,lastEnd = 10;
  2. 判断会议 2:start = 9 < lastEnd = 10,时间重叠,不安排;
  3. 判断会议 3:start = 10 ≥ lastEnd = 10,时间不重叠,安排,count = 2,lastEnd = 12;
  4. 判断会议 4:start = 11 < lastEnd = 12,时间重叠,不安排;
  • 最终结果:可安排会议数为 2,与输出一致。

六、复杂度分析

1. 时间复杂度

整体时间复杂度由「排序操作」主导,具体如下:

  • 排序操作:使用标准库sort函数,对n个会议排序,时间复杂度为O(n log n)
  • 贪心选择遍历:从第二个会议开始,遍历 n - 1 个会议,时间复杂度为O(n)
  • 总时间复杂度:O(n log n),适用于中等规模数据(如n≤10^5),处理效率较高

2. 空间复杂度

空间复杂度主要来自会议存储,为O(n):

  • 仅需一个数组 meetings 存储 n 个会议的属性,无额外复杂数据结构,空间利用率高,不会造成过多内存占用。

七、适用场景与局限性

1. 适用场景

        该算法适用于「单资源(如单个会场、单个设备)无重叠调度」且「追求资源利用率最大化(安排数量最多)」的场景,典型案例包括:

  • 会场调度:单个会议室的会议安排,确保同一时间仅一个会议进行,最大化会议安排数量。
  • 设备使用:单个打印机、投影仪等设备的使用调度,避免设备占用冲突,最大化设备使用次数。
  • 个人日程规划:个人一天内的活动安排,确保活动时间不冲突,尽可能安排更多活动。

2. 局限性

该算法并非万能,存在以下适用边界:

  • 不适用于「多资源调度」场景(如多个会场同时安排会议),此时需结合其他算法优化。
  • 无法处理「会议有优先级」的场景,需在排序阶段增加优先级判断逻辑。
  • 若存在「会议时间异常」的情况(如开始时间≥结束时间,如 “10 9”),需在输入阶段增加验证逻辑,避免排序和判断出错。
http://www.dtcms.com/a/399148.html

相关文章:

  • 凡科小程序价格嘉兴网站的优化
  • 设计模式(C++)详解——职责链模式 (Chain of Responsibility)(2)
  • 群辉nas怎么做网站品牌推广服务
  • 【RabbitMQ】RabbitMQ核心机制
  • 网站开发软件三剑客wordpress分享可见
  • GelSight Modulus 触觉型3D轮廓仪助力航空航天精密检测
  • 北京 旅游攻略 颐和园(第一天下午逛) 长城最后一天早上逛 如果到北京早 也可以第一天长城
  • 网站的做用百度做网站按点击量收费吗
  • 程序的流程方式
  • python做网站验证码常州如何进行网站推广
  • C#语法回忆零散巩固(持续更新最新版)
  • MySQL数据库——11.2事务-隔离
  • 新能源知识库(108)AGC/AVC调度算法介绍
  • cocos 零基础入门学习笔记
  • 红安城市建设局投诉网站网页设计作品欣赏分析
  • 服务器网站后台登陆密码黄框显示南沙外贸网站建设
  • 超细整理,保险项目-性能测试bug+吞吐量+并发用户数分析(详细)
  • 英语学习-Saints012
  • 游戏要怎么防御ddos攻击
  • 【echarts】指令监听响应式尺寸变化 resize()
  • 当贝桌面 4.1.6 | 完美精简版,纯净无广,可永久使用
  • [Python编程] Python3 控制流程
  • 西安网站设计哪家公司好山东网站建设价格实惠
  • JavaScript 的作用域
  • TDengine 统计函数 APERCENTILE 用户手册
  • 【分布式】分布式ID生成方案、接口幂等、一致性哈希
  • 分布式 ID 生成方案实战指南:从选型到落地的全场景避坑手册(一)
  • 对比网站做企业网站需要用到的软件
  • HAProxy 与 Tomcat
  • Tomcat 配置与使用指南