其他分享
首页 > 其他分享> > 完成所有工作的最短时间

完成所有工作的最短时间

作者:互联网

难度:困难
给你一个整数数组 jobs ,其中 jobs[i] 是完成第 i 项工作要花费的时间。

请你将这些工作分配给 k 位工人。所有工作都应该分配给工人,且每项工作只能分配给一位工人。工人的 工作时间 是完成分配给他们的所有工作花费时间的总和。请你设计一套最佳的工作分配方案,使工人的 最大工作时间 得以 最小化 。

返回分配方案中尽可能 最小 的 最大工作时间 。

示例 1:

输入:jobs = [3,2,3], k = 3
输出:3
解释:给每位工人分配一项工作,最大工作时间是 3 。

示例 2:

输入:jobs = [1,2,4,7,8], k = 2
输出:11
解释:按下述方式分配工作:
1 号工人:1、2、8(工作时间 = 1 + 2 + 8 = 11)
2 号工人:4、7(工作时间 = 4 + 7 = 11)
最大工作时间是 11 。

提示:

1 <= k <= jobs.length <= 12
1 <= jobs[i] <= 107

解法一:二分 + 状态压缩

class Solution {
public:
    int minimumTimeRequired(vector<int>& jobs, int k) {
        int n = jobs.size();
        vector<int> subsum(1 << n, 0);
        for(int i = 1; i < 1 << n; ++i){
            for(int j = 0; j < n; ++j)
                if(i & (1 << j))
                    subsum[i] += jobs[j];
        }
        int left = *max_element(jobs.begin(), jobs.end());
        int right = accumulate(jobs.begin(), jobs.end(), 0);
        while(left <= right){
            int mid = (left + right) / 2;
            if(check(jobs, k, subsum, mid))
                right = mid - 1;
            else
                left = mid + 1;
        }
        return left;
    }

    bool check(vector<int>& jobs, int k, vector<int>& subsum, int mid){
        int n = jobs.size();
        vector<long> dp(1 << n, INT_MAX);
        dp[0] = 0;
        // 从已知算未知的
        for(int mask = 0; mask < (1 << n); ++mask){
            int rem = ((1 << n) - 1) ^ mask;//剩下没算的
            for(int sub = rem; sub; sub = (sub - 1) & rem){
                if(subsum[sub] <= mid)
                    dp[sub ^ mask] = min(dp[sub ^ mask], dp[mask] + 1);
            }
        }
        return dp[(1 << n) - 1] <= k;
    }
};

标签:11,jobs,int,所有,工作,vector,完成,短时间,分配
来源: https://www.cnblogs.com/bgyx-hyyy/p/14258441.html