LC 1723. Find Minimum Time to Finish All Jobs (dp+二分)
link
普通dp:
class Solution {
public:
int n;
int minimumTimeRequired(vector<int>& jobs, int k) {
n=jobs.size();
vector<int> sum(1<<n);
for(int i=1;i<(1<<n);i++){
for(int j=0;j<n;j++){
if(i&(1<<j)){
sum[i]=sum[i-(1<<j)]+jobs[j];
break;
}
}
}
vector<vector<int>> dp(k,vector<int>(1<<n, INT_MAX));
for(int i=0;i<(1<<n);i++) dp[0][i]=sum[i];
for(int i=1;i<k;i++){
for(int j=0;j<(1<<n);j++){
if(j==0){
dp[i][j]=0;
continue;
}
for(int k=j;k>0;k=((k-1)&j)){
dp[i][j]=min(dp[i][j],max(sum[k],dp[i-1][j-k]));
}
}
}
return dp[k-1][(1<<n)-1];
}
};
二分:
class Solution {
public:
int n;
int minimumTimeRequired(vector<int>& jobs, int k) {
n=jobs.size();
vector<int> sum(1<<n);
for(int i=1;i<(1<<n);i++){
for(int j=0;j<n;j++){
if(i&(1<<j)){
sum[i]=sum[i-(1<<j)]+jobs[j];
break;
}
}
}
int left=0;
int right=0;
for(int i:jobs){
left=max(left,i);
right+=i;
}
while(left<=right){
int mid=left+(right-left)/2;
int workers=helper(mid,sum);
if(workers<=k) right=mid-1;
else left=mid+1;
}
return left;
}
int helper(int limit, vector<int>& sum){
vector<int> dp(1<<n,INT_MAX);
dp[0]=0;
for(int i=1;i<(1<<n);i++){
for(int j=i;j>0;j= ((j-1)&i)){
if(sum[j]<=limit) dp[i]=min(dp[i],1+dp[i-j]);
}
}
return dp[(1<<n)-1];
}
};