一、Problem
You want to schedule a list of jobs in d days. Jobs are dependent (i.e To work on the i-th job, you have to finish all the jobs j where 0 <= j < i).
You have to finish at least one task every day. The difficulty of a job schedule is the sum of difficulties of each day of the d days. The difficulty of a day is the maximum difficulty of a job done in that day.
Given an array of integers jobDifficulty and an integer d. The difficulty of the i-th job is jobDifficulty[i].
Return the minimum difficulty of a job schedule. If you cannot find a schedule for the jobs return -1.
Input: jobDifficulty = [6,5,4,3,2,1], d = 2
Output: 7
Explanation: First day you can finish the first 5 jobs, total difficulty = 6.
Second day you can finish the last job, total difficulty = 1.
The difficulty of the schedule = 6 + 1 = 7
二、Solution
題意:把含有依賴關係的工作分成 d 天來做,求不同工作分配方法得到的最小工作難度。
方法一:暴搜(超時)
- 第 天我們都可以把工作分成剩下的天數 d 來做,這相當於在數組上畫 條分割線,求每段區間的最大工作難度的最小的總和分割方法。
- 對於每一天,我們都可以嘗試做 個工作,所以暴搜一下分割線即可。
這題和 分割回文串 III 其實很像,但還是超時了…
class Solution {
int dfc[];
int dfs(int i, int d) {
if (d == 1) {
int max = -1;
for (int j = i; j < dfc.length; j++)
max = Math.max(max, dfc[j]);
return max;
}
int min = 0x3f3f3f3f, max = 0;
for (int j = i; j <= dfc.length - d; j++) {
max = Math.max(max, dfc[j]);
min = Math.min(min, max + dfs(j+1, d-1));
}
return min;
}
public int minDifficulty(int[] jobDifficulty , int d) {
if (jobDifficulty.length < d) return -1;
dfc = jobDifficulty;
int res = dfs(0, d);
return res;
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,
方法二:dp
- 定義狀態:
- 表示前 天完成 項任務的最小難度
- 思考狀態轉移方程:
- 對於第 天,我們可以在前 天完成 項任務(每天至少完成一項),然後在第 天完成 項任務,那麼第 天的 方程應該這樣寫:
- 但爲了取最小工作難度,所以整體的 dp 方程應該這樣寫:
- , ,因爲前 天至少有 項任務,但不能超過當前可分配任務數 。
- 綜上所述,不難得出這是一個求區間最值的問題
- 思考初始化:
- 思考輸出: 表示用 天完成 項工作的最小難度
class Solution {
public int minDifficulty(int[] dfc, int d) {
if (dfc.length < d)
return -1;
int n = dfc.length, INF = 0x3f3f3f3f, maxd[][] = new int[n][n];
for (int i = 0; i < n; i++) {
maxd[i][i] = dfc[i];
for (int j = i+1; j < n; j++)
maxd[i][j] = Math.max(maxd[i][j-1], dfc[j]);
}
int[][] dp = new int[d+1][n+1];
for (int i = 0; i <= d; i++)
for (int j = 0; j <= n; j++)
dp[i][j] = INF;
dp[0][0] = 0;
for (int i = 1; i <= d; i++)
for (int j = i; j <= n; j++)
for (int k = i-1; k < j; k++) {
dp[i][j] = Math.min(dp[i][j], dp[i-1][k] + maxd[k][j-1]);
}
return dp[d][n];
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,