题目描述
一些项目要占用一个会议室宣讲,同一个时间会议室中只能有一个项目在宣讲。给你每一个项目开始的时间和结束的时间(给你一个数组,里面是一个个具体的项目), 你来安排宣讲的日程, 要求会议室进行的宣讲的场次最多。返回这个最多的宣讲场次。
题目解析
贪心算法
问题是怎么贪心呢?
- 如果选择开始时间最早的。但是这样的话假如有一个会议开始很早,持续时间很长的话,并不是最优解
- 选择持续时间最短的。但是这样的话假如有一个持续很短的会议夹在二个会议之间,这样的话就会导致那二个会议不能进行,也不是最优解。
- 选择结束时间最早的进行排序,然后下一次安排的话我们要保证开始时间在上一次的结束时间之后,这样就算一次有效的会议安排。
贪心策略:
- 先将项目按照会议结束时间从小到大排序
- 每次选择结束时间最早的项目(如果这个项目的开始时间在前一个项目结束之后)
int bestArrange2(std::vector<std::vector<int>>intervals){
if(intervals.empty()){
return 0;
}
//结束时间早的排在前面(小根堆)
std::sort(intervals.begin(), intervals.end(), [](std::vector<int> &l, std::vector<int> &r){
return l[1] < r[1];
});
// timeline表示来到的时间点
int timeLine = 0;
// result表示安排了多少个会议
int result = 0;
// 由于刚才按照结束时间排序,当前是按照谁结束时间早的顺序遍历
for (auto & interval : intervals) {
if(timeLine <= interval[0]){
++result;
timeLine = interval[1];
}
}
return result;
}
暴力
#include <iostream>
#include <vector>
#include <random>
#include <algorithm>
#include <queue>
#include <map>
#include <list>
#include <memory>
#include <stack>
std::vector<std::vector<int>> copyButExcept(std::vector<std::vector<int>>intervals, int k){
std::vector<std::vector<int>> ans(intervals.size() - 1);
int index = 0;
for (int i = 0; i < intervals.size(); ++i) {
if(i != k){
ans[index++] = intervals[i];
}
}
return ans;
}
// 目前来到timeLine的时间点,已经安排了done多的会议,剩下的会议programs可以自由安排
// 返回能安排的最多会议数量
int process(std::vector<std::vector<int>>intervals, int done, int timeLine){
// 没有会议可以安排,返回安排了多少会议的数量
if(intervals.empty()){
return done;
}
int max = done;
// 当前安排的会议是什么会,每一个都枚举
for (int i = 0; i < intervals.size(); ++i) {
if(intervals[i][0] >= timeLine){
auto next = copyButExcept(intervals, i);
max = std::max(max, process(next, done + 1, intervals[i][1]));
}
}
return max;
}
int bestArrange1(std::vector<std::vector<int>>intervals){
if(intervals.empty()){
return 0;
}
return process(intervals, 0, 0);
}
对数器
std::default_random_engine e;
std::vector<std::vector<int>> generatePrograms(int maxLen, int minValue, int maxValue){
std::uniform_int_distribution<int> distS(1, maxLen);
std::uniform_int_distribution<int> distV(minValue, maxValue);
int size = distS(e);
std::vector<std::vector<int>> result(size, std::vector<int>(2));
for (int i = 0; i < size ; ++i) {
int v1 = distV(e);
int v2 = distV(e);
if(v1 == v2){
result[i][0] = v1;
result[i][1] = v1 + 1;
}else{
result[i][0] = std::min(v1, v2);
result[i][1] = std::max(v1, v2);
}
}
return result;
}
int main() {
std::vector<std::vector<int>> pro = {{1, 3}, {2, 3}};
printf("%d, %d\r\n", bestArrange1(pro),bestArrange2(pro));
int programSize = 12;
int timeMax = 20;
int timeTimes = 10;
for (int i = 0; i < timeTimes; i++) {
auto programs = generatePrograms(programSize, 0, timeMax);
int ans1 = bestArrange1(programs);
int ans2 = bestArrange2(programs);
if(ans1 != ans2){
printf("error");
return -1;
};
}
printf("finish!");
return 0;
}
类似题目
题目 | 思路 |
---|---|
算法:会议室宣讲场次最多 | |
leetcode:1353. 最多可以参加的会议数目 | |
leetcode:1705. 吃苹果的最大数目 |