zoukankan      html  css  js  c++  java
  • 1335工作计划的最低难度

    题目:你需要制定一份 d 天的工作计划表。工作之间存在依赖,要想执行第 i 项工作,你必须完成全部 j 项工作( 0 <= j < i)。你每天 至少 需要完成一项任务。工作计划的总难度是这 d 天每一天的难度之和,而一天的工作难度是当天应该完成工作的最大难度。给你一个整数数组 jobDifficulty 和一个整数 d,分别代表工作难度和需要计划的天数。第 i 项工作的难度是 jobDifficulty[i]。返回整个工作计划的 最小难度 。如果无法制定工作计划,则返回 -1

     

    法一:自己的代码

    思路:典型的二维动态规划题目,动态规划的两个关键地方,一是动态转移方程,二是初始条件,这个题中的初始条件可以单独计算第一列,也可以添加一列全0列,直接处理,

    from typing import List
    class Solution:
        def minDifficulty(self, jobDifficulty: List[int], d: int) -> int:
            size = len(jobDifficulty)
            dp = [[0] * d for i in range(size)]
            # 初始化,为了节省求最大值的时间
            dp[0][0] = jobDifficulty[0]
            for i in range(1,size):
                dp[i][0] = max(jobDifficulty[i], dp[i-1][0])
            # dp[row][col]表示第row+1个工作用col+1天的最小值
            for col in range(1, d):
                for row in range(col, size):
                    a,b = 0, float('inf')
                    # 这里倒序计算最大值更省时,
                    for i in range(row-1, col-2, -1):
                        a = max(a, jobDifficulty[i+1])
                        b = min(dp[i][col-1] + a, b)
                    dp[row][col] = b
                    ## 优化前的代码
                    # 一定要注意这里range(col-1,row),要从col-1开始,因为从0到col-1(包含col-1)有col个工作,恰好够col天分,一天一个,
                    # 因为dp[row][col]表示的是用col+1天分配row+1个工作,
                    # 这里dp[i][col-1]中i的初始值必须要和col-1相等,表示col-1天至少要有col-1个工作,
                    # dp[row][col] = min(dp[i][col-1]+max(jobDifficulty[i+1:row+1]) for i in range(col-1,row))
            return dp[-1][-1]
    if  __name__ == '__main__':
        solution = Solution()
        result = solution.minDifficulty(jobDifficulty = [7,1,7,1,7,1], d = 3)
        print(result)
    View Code

    法二:别人的相同思路代码

    思路:这个代码和上面的思路完全一致,只是最后求最小值的时候是用if dp[i - 1][k] + work < dp[i][j]: 的,由于是求两个数的最小值没有用min,节省了很多时间,这个技巧应该学习,

    from typing import List
    class Solution:
        def minDifficulty(self, jobDifficulty: List[int], d: int) -> int:
            jc = len(jobDifficulty)
            if d > jc: return -1
            # 注意这里定义dp的时候行列都加了1,第一行和第一列都没有用
            dp = [[-1 for i in range(jc + 1)] for i in range(d + 1)]
            # 初始化第一列
            dp[1][1] = jobDifficulty[0]
            for i in range(2, jc + 1):
                dp[1][i] = max(dp[1][i - 1], jobDifficulty[i - 1])
            for i in range(2, d + 1):
                for j in range(i, jc + 1):
                    dp[i][j] = dp[i - 1][j - 1] + jobDifficulty[j - 1]
                    work = jobDifficulty[j - 1]
                    # 仍然是倒序遍历
                    for k in range(j - 2, i - 2, -1):
                        work = max(jobDifficulty[k], work)
                        # 如果它更小,则用更小的值替代
                        if dp[i - 1][k] + work < dp[i][j]:
                            dp[i][j] = dp[i - 1][k] + work
            return dp[d][jc]
    View Code

    法三:也可用带备忘录的回溯

    参考:https://leetcode-cn.com/problems/minimum-difficulty-of-a-job-schedule/solution/python-3-jian-dan-shi-xian-hui-su-suan-fa-ji-yi-hu/

  • 相关阅读:
    CSS 的层叠上下文是什么
    BFC原理解析
    从 (a==1&&a==2&&a==3) 成立中看javascript的隐式类型转换
    IIFE中的函数是函数表达式,而不是函数声明
    Virtual DOM 真的比操作原生 DOM 快吗?
    解决for循环里获取到的索引是最后一个的问题
    bzoj4161: Shlw loves matrixI
    [NOI2007]生成树计数环形版
    bzoj1494: [NOI2007]生成树计数
    bzoj1964: hull 三维凸包
  • 原文地址:https://www.cnblogs.com/xxswkl/p/12380432.html
Copyright © 2011-2022 走看看