Loading

【leetcode】1335. 工作计划的最低难度

题目描述

点击查看题目

你需要制定一份 d 天的工作计划表。工作之间存在依赖,要想执行第 i 项工作,你必须完成全部 j 项工作( 0 <= j < i)。

你每天 至少 需要完成一项任务。工作计划的总难度是这 d 天每一天的难度之和,而一天的工作难度是当天应该完成工作的最大难度。

给你一个整数数组 jobDifficulty 和一个整数 d,分别代表工作难度和需要计划的天数。第 i 项工作的难度是 jobDifficulty[i]。

返回整个工作计划的 最小难度 。如果无法制定工作计划,则返回 -1 。


提示:
    1 <= jobDifficulty.length <= 300
    0 <= jobDifficulty[i] <= 1000
    1 <= d <= 10

思路

题目可以抽象为将n个数字分为d段,每段中最大的数字代表本段,求所有段最大值之和的最小值。

考虑动态规划,动规三个重点,状态如何表示、初始值的设置、状态转移方程。

状态用f[i,j]表示前i天做前j项工作的最小工作量;

初始值为用一天时间完成前j项工作的最小工作量;

状态转移为前i-1天完成j-k项工作,j-k+1、j-k+2、......j 项工作在第i天完成,方程表示为 f[i,j] = min( f[i-1, j-k] + max_value(j-k+1, j) );

可提前计算max_value数组,表示从i到j的最大值,代码如下

 1 class Solution {
 2     public int minDifficulty(int[] jobDifficulty, int d) {
 3         int n = jobDifficulty.length;
 4         if (n < d) return -1;
 5         int[][] f = new int[d + 1][n + 1];
 6         int[][] max = new int[n + 1][n + 1];
 7         for (int i = 1; i <= n; i++) {
 8             int max_value = -1;
 9             for (int j = i; j <= n; j++) {
10                 if (jobDifficulty[j - 1] > max_value) max_value = jobDifficulty[j - 1];
11                 max[i][j] = max_value;
12             }
13         }
14         for (int i = 1; i <= n; i++) f[1][i] = max[1][i];
15         for (int i = 2; i <= d; i++)
16             for (int j = 1; j <= n; j++)
17                 f[i][j] = Integer.MAX_VALUE;
18         for (int i = 2; i <= d; i++) {
19             for (int j = i; j <= n; j++) {
20                 for (int k = 1; j - k >= i - 1; k++) {
21                     f[i][j] = Math.min(f[i][j], f[i - 1][j - k] + max[j - k + 1][j]);
22                 }
23             }
24         }
25         return f[d][n];
26     }
27 }

 

posted @ 2020-02-18 17:09  H-utopia  阅读(374)  评论(0编辑  收藏  举报