Leetcode 1723. 完成所有工作的最短时间 (二分回溯,暴搜剪枝,状态压缩DP待续,难度较大)

这篇博客探讨了一种利用二分搜索和爆搜策略来解决如何在限定时间内分配工作给k个工人的算法。文章首先对工作进行降序排序,然后通过二分查找找到最小可能的时间限制。在爆搜过程中,通过尝试不同的工人组合并更新工作负载,检查是否能完成所有任务。整个算法注重剪枝以避免超时,确保效率。
摘要由CSDN通过智能技术生成

我们可以用二分枚举这个最小时间,对于合法的时间,总是可以安排k个工人,使得满足要求,这里需要爆搜出是否可以选出k个工人,

    bool helper(vector<int>& jobs, vector<int>& workloads, int idx, int limit){
        if(idx >= jobs.size()){
            return true;
        }
        for(int i = 0; i < workloads.size(); i++){
            if(workloads[i] + jobs[idx] <= limit){
                workloads[i] += jobs[idx];
                if(helper(jobs, workloads, idx + 1, limit)){
                    return true;
                }
                workloads[i] -= jobs[idx];
                if(workloads[i] == 0){
                    break;
                }
            }
        }
        return false;
    }

以上就是爆搜的过程,需要按时间进行从大到小,排队,进行一个剪枝,否则会超时。

完整代码

class Solution {
public:
    int minimumTimeRequired(vector<int>& jobs, int k) {
        sort(jobs.begin(), jobs.end(), greater<int>());
        int left = jobs[0], right = accumulate(jobs.begin(), jobs.end(), 0);
        while(left <= right){
            int mid = (left + right) / 2;
            if(check(jobs, k, mid)){
                right = mid - 1;
            }else{
                left = mid + 1;
            }
        }
        return left;
    }

    bool check(vector<int>& jobs, int k, int limit){
        // 能否将jobs分成k份,使得每一份时间之和均小于limit
        vector<int> workloads(k);
        return helper(jobs, workloads, 0, limit);
    }

    bool helper(vector<int>& jobs, vector<int>& workloads, int idx, int limit){
        if(idx >= jobs.size()){
            return true;
        }
        for(int i = 0; i < workloads.size(); i++){
            if(workloads[i] + jobs[idx] <= limit){
                workloads[i] += jobs[idx];
                if(helper(jobs, workloads, idx + 1, limit)){
                    return true;
                }
                workloads[i] -= jobs[idx];
                if(workloads[i] == 0){
                    break;
                }
            }
        }
        return false;
    }
};

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值