日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

LeetCode 1723. 完成所有工作的最短时间(DFS+剪枝 / 状态压缩DP)

發布時間:2024/7/5 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LeetCode 1723. 完成所有工作的最短时间(DFS+剪枝 / 状态压缩DP) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 1. 題目
    • 2. 解題
      • 2.1 DFS
      • 2.2 狀態壓縮DP

265 / 3871, 前6.85%

前3題題解:

  • LeetCode 5649. 解碼異或后的數組(位運算)
  • LeetCode 5652. 交換鏈表中的節點(快慢指針)
  • LeetCode 5650. 執行交換操作后的最小漢明距離(并查集)

1. 題目

給你一個整數數組 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 號工人:128(工作時間 = 1 + 2 + 8 = 112 號工人:47(工作時間 = 4 + 7 = 11) 最大工作時間是 11 。提示: 1 <= k <= jobs.length <= 12 1 <= jobs[i] <= 10^7

https://leetcode-cn.com/problems/find-minimum-time-to-finish-all-jobs/

2. 解題

2.1 DFS

  • 先排序,也可以不排序
  • 使用 DFS 暴力搜索,過程中進行剪枝
class Solution {int ans = INT_MAX; public:int minimumTimeRequired(vector<int>& jobs, int k) {int n = jobs.size();// 不排序 88mssort(jobs.begin(), jobs.end()); // 40ms// sort(jobs.rbegin(), jobs.rend()); // 680msvector<int> time(k, 0);dfs(jobs, time, k, 0);return ans;}void dfs(vector<int>& jobs, vector<int>& time, int k, int idx){if(idx == jobs.size()){int t = *max_element(time.begin(), time.end());if(t < ans)// 最大的時間總和 更小ans = t;return;}for(int i = 0; i < k; ++i){if(time[i]+jobs[idx] > ans)//如果某人的時間超過答案,不可能是更優答案,剪枝continue;time[i] += jobs[idx];dfs(jobs, time, k, idx+1);time[i] -= jobs[idx];if(time[i] == 0)break;//搜完了,不加會超時}} };

40 ms 7.6 MB C++

2.2 狀態壓縮DP

  • 參考大佬題解

類似題目:LeetCode 1178. 猜字謎(狀態壓縮+枚舉二進制子集+哈希)

class Solution { public:int minimumTimeRequired(vector<int>& jobs, int k) {int n = jobs.size();// 使用 12 位二進制數的 0,1 表示某個工作分配了沒vector<int> time(1<<n, 0);for(int i = 1; i < (1<<n); ++i){for(int j = 0; j < n; ++j){if((i & (1<<j)) == 0)continue;int left = i - (1<<j);//除去 j 工作外的工作time[i] = time[left]+jobs[j];}}vector<vector<int>> dp(k, vector<int>(1<<n, INT_MAX));// dp[k][sub] 表示 前 k 個人,處理 sub 任務子集 的最優分配時間for(int i = 0; i < (1<<n); ++i)dp[0][i] = time[i];for(int ki = 1; ki < k; ++ki){for(int i = 0; i < (1<<n); ++i){for(int s = i; s; s = i&(s-1))//枚舉 i 的全部子集{int left = i - s;int t = max(dp[ki-1][left], time[s]);dp[ki][i] = min(dp[ki][i], t);}}}return dp[k-1][(1<<n)-1];} };

1352 ms 11.2 MB C++

附枚舉子集 for(int s = i; s; s = (s-1) & i)

#include<bits/stdc++.h> using namespace std; int main() {char buf[50];for(int i = 6; i <= 8; i++){cout << i << endl;for(int s = i; s; s = (s-1)&i){itoa(s, buf, 2);printf(buf);printf("\n");}cout << "--------" << endl;}return 0; } 6 110 100 10 -------- 7 111 110 101 100 11 10 1 -------- 8 1000 -------- 請按任意鍵繼續. . .

我的CSDN博客地址 https://michael.blog.csdn.net/

長按或掃碼關注我的公眾號(Michael阿明),一起加油、一起學習進步!

總結

以上是生活随笔為你收集整理的LeetCode 1723. 完成所有工作的最短时间(DFS+剪枝 / 状态压缩DP)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。