https://leetcode.com/problems/find-minimum-time-to-finish-all-jobs/ from Google
Thinking process:
The concept for this is actually simple. We can use a bitmap to represent what jobs have been done. dp[i][j] means the minimum Hamming when first i person finishing jobs represented by j. Since there’s only 12 jobs, j will be less than 4096. To calculate dp[i][j], we check every possible subset l in j, and delegate l to person i, which means that first i-1 person should complete j-l jobs, which is dp[i-1][j-l].
We use another cache called dp2 to cache the working time for each l so that we don’t need to compute the time again and again.
Here is the code.
1class Solution {
2public:
3 vector<int> j;
4 vector<int> dp2;
5 int N;
6 int dp[12][4096];
7 int calTime(int x) {
8 if (dp2[x] != INT_MAX) return dp2[x];
9 int ret = 0;
10 for (int i=0; i<N; i++) {
11 if (x & (1<<i)) ret += j[i];
12 }
13 return dp2[x] = ret;
14 }
15 int minimumTimeRequired(vector<int>& jobs, int k) {
16 N = jobs.size();
17 j = jobs;
18 for (int i=0; i<12; i++) for (int j=0; j<4096; j++) dp[i][j] = INT_MAX;
19 dp2.resize(1<<N, INT_MAX);
20 for (int i=1; i<(1<<N); i++) {
21 dp[0][i] = calTime(i);
22 }
23 for (int i=1; i<k; i++) {
24 for (int j=1; j<(1<<N); j++) {
25 for (int l=j; l>0; l=j&(l-1)) {
26 dp[i][j] = min(dp[i][j], max(calTime(l), dp[i-1][j-l]));
27 }
28 }
29 }
30 return dp[k-1][(1<<N)-1];
31 }
32};