java编程

文章描述了一道关于任务调度的编程题,要求计算在考虑冷却时间约束下完成所有任务的最短时间。解决方案是通过优先处理相同任务多的任务,利用TreeSet存储空闲时间并进行动态扩容,以达到时间利用率的最大化。
摘要由CSDN通过智能技术生成

华为OD机试

任务最优调度

题目

【任务最优调度】给定一个正整数组表示待系统执行的任务列表,数组的每一个元素代表一个任务,元素的值表示该任务的类型。请计算执行完所有任务所需的最短时间。
任务执行规则如下:
1、任务可以按任意顺序执行,且每个任务执行耗时间均为1个时间单位。
2、两个同类型的任务之间必须有长度为N个单位的冷却时间,比如N为2时,在时间K执行了类型3的任务,那么K+1和K+2两个时间不能执行类型3任务。
3、系统在任何一个单位时间内都可以执行一个任务,或者等待状态。说明:数组最大长度为1000,速度最大值1000。
输入描述:
第一行记录一个用半角逗号分隔的数组,数组长度不超过1000,数组元素的值不超过1000第二行记录任务冷却时间,N为正整数,N<=100。
输出描述:
输出为执行完所有任务所需的最短时间。
示例:
输入
2,2,2,3
2
输出
7

思路

模拟任务调度的过程
首先导致时间利用率低的是冷却时间,只要将冷却时间被合理利用则整体时间就会越低。因为相同任务越多的产生冷却时间的也就越多,而相同任务越少的可以作为对前面产生冷却时间利用的合理利用,所以相同任务多的先分配相同任务少的后分配。
分配时可以使用一个数据结构记录当前剩余可用的空闲时间(包括冷却时间)供后面任务使用,为了快速锁定任务调度时间可以使用数据结构TreeSet作为空闲时间的存储

代码

@Test
    public void test32(){
        Scanner scanner=new Scanner(System.in);
        String str=scanner.nextLine();
        HashMap<Integer,Integer> map=new HashMap<>();
        Arrays.stream(str.split(",")).mapToInt(Integer::parseInt).forEach(el->map.merge(el,1, Integer::sum));
        Integer nums[] =map.values().stream().sorted((x,y)->y-x).toArray(Integer[]::new);//按不同任务多少降序排序
        TreeSet<Integer> times=new TreeSet<>();//记录当前从1到最大的使用时间之间的空闲时间
        int n=scanner.nextInt();//n为冷却时间
        IntStream.range(1,n+1).forEach(times::add);//设置初始空闲时间为1~n
        int maxTime=Integer.MIN_VALUE;//记录任务被调度的最长时间
        for(int index=0;index<nums.length;index++){//遍历每一种任务
            Integer temp=nums[index],position=times.first();//position是当前任务执行时间
            while (temp>0){
                if(times.ceiling(position)==null){//找不到合适时间对时间进行扩容
                    IntStream.range(maxTime+1,maxTime+n+2).forEach(times::add);//从占用最大位置时间开始扩容
                }
                position=times.ceiling(position);//查找到下一个空闲时间
                maxTime=Math.max(maxTime,position);//记录任务调度最久的时间
                times.remove(position);//该空闲时间已经使用移除掉
                position+=n+1;//获取下一个可以调度该任务的最低时间
                temp--;
            }
        }
        System.out.println(maxTime);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值