活动安排问题

14天阅读挑战赛

算法知识点

活动安排问题是可以利用贪心算法求解的经典案例,该问题要求尽可能多的利用某一公共资源,使尽可能多的活动用上公共资源。本次活动安排以会议安排为例,讲解如何在有限的时间内安排更多场次的会议。

算法题目描述

某跨国公司总裁在某一天有多场会议可以参加,但当中有的会议时间是冲突的,但总裁希望能尽量参与更多场次的会议,请你为总裁规划一个最佳方案。

原始会议表:
会议号id12345678910
开始start31525386812
结束end64759811101214

做题思路

对会议按结束时间排序

  • 根据结束时间从早到晚排序
  • 当结束时间相同时,按开始时间从晚到早排序

贪心策略

  • 首先选择第一个最早结束的会议
  • 记录当前会议结束时间last
  • 依次从未安排会议中选取满足开始时间>=last的会议
  • 如果会议开始时间>=last,会议相容,可安排,否则不可安排
  • 遇到可安排的会议时,更新last
  • 重复以上步骤,直到遍历完最后一个会议

由于进行了时间排序,所以在会议选择上,自需要考虑会议的开始时间是否>=上一个会议的结束时间last,如果会议开始时间>=last,那么说明两个会议不重合,这个会议可以被按安排进来,更新last为新加入会议的结束时间,然后接着往下找,直到遍历完排序后的会议数组

排序后的会议表
会议号id24136587910
开始start12353568812
结束end45678910111214
贪心选择过程
会议号id24136587910
开始start12353568812
结束end45678910111214
  • 选取会议:2
  • 结束时间 last = 4

会议号id24136587910
开始start12353568812
结束end45678910111214
  • 选取会议:2 - 3
  • 结束时间 last = 7

会议号id2413 6587910
开始start12353568812
结束end45678910111214
  • 选取会议:2 - 3 - 7
  • 结束时间 last = 11

会议号id24136587910
开始start12353568812
结束end45678910111214
  • 选取会议:2 - 3 - 7 - 10
  • 结束时间 last = 14

遍历完排序后的会议数组,算法到此结束,得到的最优会议安排为:2 - 3 - 7 - 10,共 4 个会议。

模板代码

import java.util.Arrays;
import java.util.Comparator;
public class MeetArrangement {
    public static void main(String[] args) {
        //这里是顺序排列的会议1、2、3、4、5、6、7、8、9、10
        int[] start = {3,1,5,2,5,3,8,6,8,12};
        int[] end = {6,4,7,5,9,8,11,10,12,14};
        System.out.println(new MeetArrangement().meetArrangement(start,end));
    }

    //会议类,将每一个会议信息封装成对象
    class Meet{
        private int id;
        private int start;
        private int end;
        public Meet(int id, int start, int end) {
            this.id = id;
            this.start = start;
            this.end = end;
        }
    }
    
    //核心方法,结果以会议号的字符串返回
    public String meetArrangement(int[] start, int[] end){
        String result = "";
        Meet[] meetArr = new Meet[start.length];
        //每一个会议信息封装成对象
        for(int i=0;i<end.length;i++){
            Meet m = new Meet(i+1,start[i],end[i]);
            meetArr[i]=m;
        }
        //排序:Comparator比较器用于实现对象的排序
        Arrays.sort(meetArr, new Comparator<Meet>() {
            @Override
            public int compare(Meet o1, Meet o2) {
                //排序规则1:结束时间相等,开始时间慢的排前面
                if(o1.end==o2.end){
                    return o2.start-o1.start;
                }
                //排序规则2:结束时间不相等,结束时间早的排前面
                return o1.end-o2.end;
            }
        });
        //贪心选择过程
        //初始化,第一个会议直接添加,结束时间为当前last
        result +=meetArr[0].id;
        int last=meetArr[0].end;
        for(int i=1;i<meetArr.length;i++){
            if(meetArr[i].start>=last){
                result = result+"-"+meetArr[i].id;
                last = meetArr[i].end;
            }
        }
        return result;
    }
}

   //输出结果:2-3-7-10

【注:文章部分内容参考自《趣学算法》】

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值