算法:会议室宣讲场次最多

题目描述

一些项目要占用一个会议室宣讲,同一个时间会议室中只能有一个项目在宣讲。给你每一个项目开始的时间和结束的时间(给你一个数组,里面是一个个具体的项目), 你来安排宣讲的日程, 要求会议室进行的宣讲的场次最多。返回这个最多的宣讲场次。

题目解析

贪心算法

问题是怎么贪心呢?

  • 如果选择开始时间最早的。但是这样的话假如有一个会议开始很早,持续时间很长的话,并不是最优解

在这里插入图片描述

  • 选择持续时间最短的。但是这样的话假如有一个持续很短的会议夹在二个会议之间,这样的话就会导致那二个会议不能进行,也不是最优解。

在这里插入图片描述

  • 选择结束时间最早的进行排序,然后下一次安排的话我们要保证开始时间在上一次的结束时间之后,这样就算一次有效的会议安排。

在这里插入图片描述

贪心策略:

  • 先将项目按照会议结束时间从小到大排序
  • 每次选择结束时间最早的项目(如果这个项目的开始时间在前一个项目结束之后)
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. 吃苹果的最大数目
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值