完成所有工作的最短時間
阿新 • • 發佈:2021-01-10
難度:困難
給你一個整數陣列 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; } };