1723. 完成所有工作的最短时间

  1. 完成所有工作的最短时间
    给你一个整数数组 jobs ,其中 jobs[i] 是完成第 i 项工作要花费的时间。
    请你将这些工作分配给 k 位工人。所有工作都应该分配给工人,且每项工作只能分配给一位工人。工人的 工作时间 是完成分配给他们的所有工作花费时间的总和。请你设计一套最佳的工作分配方案,使工人的 最大工作时间 得以 最小化 。
    返回分配方案中尽可能 最小 的 最大工作时间 。

参考官方题解的第一个思路
总体思路:最大工作时间的下限是所有工作时间中最大的一个,上限是所有工作的时间和,采用二分法,对上下限之间的值进行判断,若能否成功执行分配任务,上限修改为中间值(此处不宜设置为mid+1,mid+1可能是一个失败的值),若不能,下限修改为中间值+1.
判断能否执行分配任务时使用递归回溯策略。在判断第j项任务时,数组workload存放每一个工人当前已被分配的任务(包括前j-1项),若当前任务分配给i,workload不大于limit,则接着判断j+1能否分配。若所有的任务都可以分配,则说明存在一种分配方案,使得上限为limit成功实现,将结果反馈到main函数,修改上限right值。若不能分配,修改下限left值。

优化:

  1. 先分配所用时间较长的任务。
  2. 当前任务分配给i时,若分配失败且i当前的任务量为0,则i之后的工作人员已分配的任务也为0,分配方式和i是一样的,所以此时可以剪枝。
  3. (未理解)若将j分配给i之后,i的工作量恰好为limit,且后续分配失败,那么不存在一种成功的方案,可以将j分配给i之后的工作人员。
bool traceback(vector<int>&jobs,vector<int>&workload,int index,int limit){
        if(index>=jobs.size()){
            return true;
        }
        int cur=jobs[index];
        for(auto&x:workload){
            if(x+cur<=limit){
                x+=cur;
                if(traceback(jobs,workload,index+1,limit)){
                    return true;
                }
                x-=cur;//分配失败时,一定要把分配给x的任务减掉
            }
            if(x==0){
                break;
            }
        }
        return false;
    }

    bool check(vector<int>&jobs,int k,int limit){
        vector<int>workload(k);
        return traceback(jobs,workload,0,limit);
    }

    int minimumTimeRequired(vector<int>& jobs, int k) {
        sort(jobs.begin(),jobs.end(),greater<int>());
        int l=jobs[0],r=accumulate(jobs.begin(),jobs.end(),0),mid;
        while(l<r){
            mid=(l+r)>>1;//位运算求中值
            if(check(jobs,k,mid)){
                r=mid;//分配成功则修改上限
            }else{
                l=mid+1;//分配失败则修改下限
            }
        }
        return l;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值