力扣每日一题+python知识点回顾(五)

力扣题目:做菜顺序(题号:1402)

一个厨师收集了他n道菜的满意程度satisfaction,这个厨师做出每道菜的时间都是1单位时间。

一道菜的「 like-time 系数 」定义为烹饪这道菜结束的时间(包含之前每道菜所花费的时间)乘以这道菜的满意程度,也就是time[i]*satisfaction[i]

返回厨师在准备了一定数量的菜肴后可以获得的最大like-time系数 总和。

你可以按任意顺序安排做菜的顺序,你也可以选择放弃做某些菜来获得更大的总和。

示例1:

输入:satisfaction = [-1,-8,0,5,-9]
输出:14
解释:去掉第二道和最后一道菜,最大的 like-time 系数和为 (-11 + 02 + 5*3 = 14) 。每道菜都需要花费1单位时间完成。

示例2:

输入:satisfaction = [4,3,2]
输出:20
解释:可以按照任意顺序做菜 (21 + 32 + 4*3 = 20)

示例3:

输入:satisfaction = [-1,-4,-5]
输出:0
解释:大家都不喜欢这些菜,所以不做任何菜就可以获得最大的 like-time 系数

编程思路:动态规划

先我们来看like-time的计算公式:time[i]*satisfaction[i],要想like-time 系数总和最大,那么每一个 like-time 都要尽可能大。因此两个乘数都要尽可能的大,即 time 和 satisfaction 都要尽可能大。那么我们可以得出一个结论:满意度越大的菜,越靠后做,这样时间因子就会更大。

有以下两种情况:

  1. 当满意度为正时,like-time系数也是正的, 这些菜就按照满意度从低到高依次做就行。
  2. 当满意度为负时,这个菜的作用就是堆时间量,当增加这个菜导致的满意度减少与时间量增加的差值是为正是,可以考虑加入选择。

因此我们得出一下设计方案:
我们先将做菜顺序按满意度从低到高排序,然后通过反向思维来考虑,如果我们只选择一道菜,我们是否选择做菜,做哪道菜?选取最佳方案,再此基础上选取只做两道菜时的方案,通过对比所有方案,保存like-time系数最大的方案,以此倒推,直到我们便利完所有菜,查询最大like-time系数时选择的菜的做菜顺序可得最终答案。

编程代码:

class Solution:
def maxSatisfaction(self, satisfaction: List[int]) -> int:
    l = len(satisfaction)
    dp = [[0 for _ in range(l + 1)] for _ in range(l + 1)]
    satisfaction.sort()
    ans = 0
    for i in range(1 , l + 1):
        for j in range(1 , i + 1):
            dp[i][j] = dp[i - 1][j - 1]+satisfaction[ i - 1 ] * j #求使用上这道菜的值
            if j < i:
                dp[i][j] = max(dp[i][j],dp[i - 1][j])#判断是否做这道菜
            ans = max(ans,dp[i][j])
    return ans
posted @ 2023-10-23 20:06  风雪无常  阅读(8)  评论(0编辑  收藏  举报