当前位置:网站首页>[leetcode daily question 2021/5/8]1723. The shortest time to complete all work
[leetcode daily question 2021/5/8]1723. The shortest time to complete all work
2022-07-26 10:39:00 【LittleSeedling】
1723. The shortest time to complete all the work
The title comes from leetcode, Solutions and ideas represent only personal views . Portal .
difficulty : difficult ( The idea is right , But I can't think of a way to enumerate subsets quickly , No timeout )
Time :-
TAG: Dynamic programming
subject
Give you an array of integers jobs , among jobs[i] Is to complete the first i The time it takes to do this job .
Please assign these jobs to k Workers . All work should be assigned to workers , And each job can only be assigned to one worker . The worker's working hours Is the sum of the time it takes to complete all the work assigned to them . Please design the best work assignment plan , Make the workers Maximum working hours To be able to To minimize the .
Return to the distribution scheme as much as possible Minimum Of Maximum working hours .
Example 1:
Input :jobs = [3,2,3], k = 3
Output :3
explain : Assign each worker a job , The maximum working time is 3 .
Example 2:
Input :jobs = [1,2,4,7,8], k = 2
Output :11
explain : Work is distributed as follows :
1 Worker number one :1、2、8( working hours = 1 + 2 + 8 = 11)
2 Worker number one :4、7( working hours = 4 + 7 = 11)
The maximum working time is 11 .
Tips :
1 <= k <= jobs.length <= 12
1 <= jobs[i] <= 107
Ideas
You can see ,1 <= k <= jobs.length <= 12, So this question to flash back It should be solvable .( But if nothing is done at all , It must be over time ( Because it's a difficult problem ), So we should also consider the problem of reducing branches ).
If you have done similar problems before , You can know , This is the problem CPU Scheduling problem .
- If you use greedy solution , We can get a better solution in a short time ( But not necessarily the best ).
- The problem requires the optimal solution , Then it's similar Travel agent problem , Need to use to flash back / Dynamic programming solution .
I was thinking about to flash back Namely The top-down + Memorandum The way , So I plan to use Dynamic planning is bottom-up solution ( Faster ?).
I see... In the back Official answer ( Two points + to flash back + Pruning ), After running for a while, it's still two minutes fast .( Two points + to flash back 0ms, Kinesiology 500ms)
Dynamic programming
Define an array d p [ i ] [ j ] dp[i][j] dp[i][j].
i i i Show consideration [ 0 , i ] [0,i] [0,i] Worker number one . 0 ≤ i < k 0 \leq i \lt k 0≤i<k.
j j j Indicates the jobs that workers can choose . 0 ≤ j < 2 n 0\leq j \lt 2^n 0≤j<2n.
j j j Use every representative jobs Selection of .1 For the selection ,0 Is not selected .
For example, in the example 2 in , n = 5 n=5 n=5.
When j = 7 j=7 j=7( Binary for 111) Indicated selection jobs[0],jobs[1],jobs[2].
When j = 5 j=5 j=5( Binary for 101) Indicated selection jobs[0],jobs[2].
Array d p [ i ] [ j ] dp[i][j] dp[i][j] Show consideration [ 0 , i ] [0,i] [0,i] Worker number one , The available jobs are j j j, Then the minimum maximum working time in the allocation scheme ( Sub problem ). Final answer d p [ k − 1 ] [ 2 n − 1 ] dp[k-1][2^n-1] dp[k−1][2n−1] That's what the original topic asked .
For example 1 in , n = 3 , k = 3 n=3,k=3 n=3,k=3, d p [ 1 ] [ 5 ] dp[1][5] dp[1][5] It means there are 2 One worker , The jobs you can choose are jobs[0],jobs[2], Then the minimum and maximum working time in the allocation scheme .
that , Final answer d p [ 2 ] [ 7 ] dp[2][7] dp[2][7] It's what you want .
State transition equation
When only 1 When a worker , We initialize the boundary conditions d p [ 0 ] [ j ] dp[0][j] dp[0][j]
d p [ 0 ] [ j ] dp[0][j] dp[0][j] It is equal to the sum of all selected jobs .
d p [ 0 ] [ j ] = ∑ i = 0 n ( j o b s [ i ] i f ( 2 i & j ) e l s e 0 ) dp[0][j] = \sum_{i=0}^n( jobs[i] ~ if ~(2^i\&j) ~else~0) dp[0][j]=i=0∑n(jobs[i] if (2i&j) else 0)
about d p [ i ] [ j ] dp[i][j] dp[i][j] We need to enumerate number i i i Worker No. is j j j Case selection . Enumeration j j j Subset p.
then , Calculation max( The first i i i The time spent by worker No , The first [ 0 , i − 1 ] [0,i-1] [0,i−1] Worker No. is p p p About j j j The complement of Spend the minimum time on ).
for example j = 7 j=7 j=7. p = 4 p=4 p=4 yes j j j A subset of . q = 3 q=3 q=3 yes p p p About j j j The complement of .
then , For the first i i i Each selection of worker No ( j j j Every subset of ), Let's take a minimum .
In short , Current workers i i i The case that can be selected is j j j, So workers i i i stay j j j Pick it up at will , Leave the rest to the workers [ 0 , i − 1 ] [0,i-1] [0,i−1].
Optimize
There are two optimizations .
- When you know that the selection is j j j when , Know quickly s u m = ∑ i = 0 n ( j o b s [ i ] i f ( 2 i & j ) e l s e 0 ) sum=\sum_{i=0}^n( jobs[i] ~ if ~(2^i\&j) ~else~0) sum=∑i=0n(jobs[i] if (2i&j) else 0) How much is the .
For example, in the example 2 in , j = 5 j=5 j=5,sum = jobs[0]+jobs[2] = 5.
- Quick enumeration j j j Subset .
Sum and make a table
For the selection case is j j j, The easiest way is Enumerate j j j Every one of them , Yes 1 It means choosing . The code is as follows :
int nbit = pow(2,n);
for(int j=1;j<nbit;j++){
for(int q=0;q<n;q++){
int mask = pow(2,q);
// If the first q Bit is selected ( Selected as 1)
if(mask & j){
sum += jobs[q];
}
}
}
But this way Time complexity That's it. O( 2 n ⋅ n 2^n \sdot n 2n⋅n). Is there any way to calculate faster ?
We Can you pass the previous calculation , Establish the transfer equation ?
In fact, we observe, for example j = 6 j=6 j=6( Binary for 110) when , If 1102 Change only one , Then we can go through selectJobs[6] = jobs[2] + selectJobs[0102] perhaps jobs[1] + selectJobs[1002] obtain .
So can we find a way to change only one digit ? We need some experience here .
We need to know x & (x-1) What does it mean ?
x & (x-1) Is to eliminate x The lowest of all 1.
that ,y = j - x Is the lowest position eliminated .
for example , j = 6 j=6 j=6
x = 6 & 5 = 11 0 2 & 10 1 2 = 4 ( 10 0 2 ) x = 6 \& 5 =110_2 \& 101_2 = 4(100_2) x=6&5=1102&1012=4(1002)
y = 6 − 4 = 11 0 2 − 10 0 2 = 2 ( 01 0 2 ) y = 6-4=110_2-100_2 = 2(010_2) y=6−4=1102−1002=2(0102)
Last , Use Logarithm exchange formula With the y, Got it. jobs The corresponding subscript .
Logarithm exchange formula :
l o g a b = l o g c b l o g c a log_ab = {log_c b \over log_c a} logab=logcalogcb
int nbit = pow(2,n);
// initialization The sum of each subset
vector<int> selectJobs(nbit,0);
for(int j=1;j<nbit;j++){
int x = j & (j-1);
int y = j - x;
selectJobs[j] = selectJobs[x] + jobs[log(y)/log(2)];
}
Quickly enumerate each selection j j j Subset p p p
The simplest solution is , Enumerate again [ 1 , j ] [1,j] [1,j], If p & j > 0 p\&j \gt 0 p&j>0 explain p p p yes j j j A subset of .
int nbit = pow(2,n);
for(int j=1;j<nbit;j++){
for(int p=1;p<j;p++){
if(j&p){
// If p yes j A subset of
int sum = selectJobs[p];
int not_p_in_j = (~p) & j;
int maxTime = max(sum,dp[i-1][not_p_in_j]);
dp[i][j] = min(dp[i][j],maxTime);
}
}
}
But the time complexity is O( 2 n ⋅ 2 n 2^n\sdot 2^n 2n⋅2n), The wife is slow . Is there any way to calculate faster ?
According to the previous x & (x-1) Inspiration of meaning ( In fact, I didn't figure it out ), In short, you need to enumerate j j j Subset , Just use the following code :
//p=0 End of time
for(int p=j;p;p=(p-1)&j){
//TO DO
}
Code
class Solution {
public:
int minimumTimeRequired(vector<int>& jobs, int k) {
int n = jobs.size();
int nbit = pow(2,n);
vector<vector<int>> dp(k,vector<int>(nbit,INT_MAX/2));
// initialization The sum of each subset
vector<int> selectJobs(nbit,0);
for(int j=1;j<nbit;j++){
int x = j & (j-1);
int y = j - x;
selectJobs[j] = selectJobs[x] + jobs[log(y)/log(2)];
}
// initialization dp[0][i]
for(int i=0;i<nbit;i++){
dp[0][i] = selectJobs[i];
}
// Start dp
for(int i=1;i<k;i++){
// Enumerate the selection
for(int j=1;j<nbit;j++){
// enumeration j Subset
for(int p=j;p;p=(p-1)&j){
int sum = selectJobs[p];
int not_p_in_j = (~p) & j;
// perhaps not_p_in_j = j - p;
int maxTime = max(sum,dp[i-1][not_p_in_j]);
dp[i][j] = min(dp[i][j],maxTime);
}
}
}
return dp[k-1][nbit-1];
}
};
Algorithm complexity
Time complexity : O( k ⋅ 3 n k \sdot 3^n k⋅3n). among n It's an array jobs The length of ,k For the number of workers . We need to O( 2 n 2^n 2n) Time preprocessing selectJobs Array . The inner loop complexity is only O( 3 n 3^n 3n) instead of O( 2 n ⋅ 2 n 2^n \sdot 2^n 2n⋅2n) = O( 4 n 4^n 4n).
Therefore, the time complexity of dynamic programming is O( k ⋅ 3 n k\sdot 3^n k⋅3n), So the total time complexity is O( k ⋅ 3 n k \sdot 3^n k⋅3n).
Spatial complexity : O( k ⋅ 2 n k \sdot 2^n k⋅2n). among n It's an array jobs The length of ,k For the number of workers . Used to store dp Array .

Official answer dp There can be 500ms, I don't know where it's slow .
边栏推荐
猜你喜欢

数据分析入门 | kaggle泰坦尼克任务(一)—>数据加载和初步观察
![[Halcon vision] threshold segmentation](/img/1c/e2463a796f99804a55680b69e714a6.png)
[Halcon vision] threshold segmentation

.NET5WTM(ASP.NET Core) PGSql开箱操作

mysql20210906

粽子大战 —— 猜猜谁能赢

抽象工厂及其改进示例

【机器学习小记】【搭建循环神经网络及其应用】deeplearning.ai course5 1st week programming(keras)

Introduction to data analysis | kaggle Titanic mission (I) - > data loading and preliminary observation

数据分析入门 | kaggle泰坦尼克任务
![[Halcon vision] morphological expansion](/img/ce/abaca036fce5b67dfe6ac361aecfea.png)
[Halcon vision] morphological expansion
随机推荐
Asynctask < T> decoration and await are not used in synchronous methods to obtain asynchronous return values (asynchronous methods are called in synchronous methods)
.NET操作Redis sorted set有序集合
剑指Offer(二十):包含min函数的栈
Okaleido ecological core equity Oka, all in fusion mining mode
MD5 encryption
扫雷pro版2021-08-19
RT-Thread 学习笔记(三)---用SCons 构建编译环境
Oracle创建索引
【dectectron2】跟着官方demo一起做
【论文下饭】Deep Mining External Imperfect Data for ChestX-ray Disease Screening
A semicolon is missing
STM32 阿里云MQTT esp8266 AT命令
比较器(Comparable与Comparator接口)
移动端H5开发常用技巧总结
RT-Thread 学习笔记(八)---开启基于SPI Flash的elmfat文件系统(下)
第4期:大学生提前职业技能准备之一
Simple use of json-c Library -- converting JSON files to struct
[leetcode每日一题2021/8/30]528. 按权重随机选择【中等】
少了个分号
剑指Offer(五十二):正则化表达式