会议安排
- 要求:设有n个会议等待安排,⽤贪⼼法找出满⾜⽬标要求的会议集合。这些会议按结束时间的⾮减序排列.
- 现在以11个会议安排为例,如下标所示:
会议i | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
---|---|---|---|---|---|---|---|---|---|---|---|
会议开始时间 b i b_i bi | 1 | 3 | 0 | 5 | 3 | 5 | 6 | 8 | 8 | 2 | 12 |
会议结束时间 e i e_i ei | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
这里的贪心算法怎么贪呢?有以下三种思路:
- 选择最早开始时间且不与已安排会议重叠的会议
- 选择使⽤时间最短且不与已安排会议重叠的会议
- 选择具有最早结束时间且不与已安排会议重叠的会议
这里选择第三种,为什么呢?因为这里要使得会议数量越多,其实核心思想是:在选中会议的时,空出最多的时间! 这样,能保证在选定会议时,当前达到最优,后面的会议仍然能够有时间,这样推出全局最优。
代码如下:
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
struct node {
int _start;
int _end;
int index;
node(int _start, int _end, int index) {
this->_start = _start;
this->_end = _end;
this->index = index;
}
};
bool operator<(const node &n1, const node &n2 ) {
return n1._end > n2._end;
}
using namespace std;
int main() {
int n = 0;
printf("请输入要申请的会议数量 : ");
scanf("%d", &n );
printf("请输入会议开始时间和会议结束时间。\n");
int _start, _end;
// 优先队列,储存输入进来的数据
priority_queue<node> pq;
// 队列,存储最终的结果
queue<node> res;
// 输入会场数据
for (int i = 0; i < n; i++) {
scanf("%d%d", &_start, &_end );
pq.push(node(_start, _end, i + 1));
}
// 最早结束时间
int end_time = -1;
while (pq.empty() == false ) {
node n = pq.top();
pq.pop();
// 后一场的开始时间 小于 大于或等于上一场的结束时间
if (n._start >= end_time) {
// 选中当前的会议
res.push(n);
// 改变结束时间
end_time = n._end;
}
}
// 选中会议的个数
int len = res.size();
// 依次打印会议信息
while (res.empty() == false ) {
node tmp = res.front();
res.pop();
printf("第%d场会议 : %d : %d \n", tmp.index, tmp._start, tmp._end );
}
printf("总共%d场会议\n", len);
return 0;
}
输出如下: