🌸1.做菜顺序
一个厨师收集了他 n 道菜的满意程度 satisfaction ,这个厨师做出每道菜的时间都是 1 单位时间。
一道菜的 「喜爱时间」系数定义为烹饪这道菜以及之前每道菜所花费的时间乘以这道菜的满意程度,也就是 time[i]*satisfaction[i] 。
请你返回做完所有菜 「喜爱时间」总和的最大值为多少。
你可以按 任意 顺序安排做菜的顺序,你也可以选择放弃做某些菜来获得更大的总和。
题目链接:做菜顺序https://leetcode-cn.com/problems/reducing-dishes/
🌸题目分析:首先我们要准备,对于这个满意程度是在取值是可以为负数的。这也就导致我们当我们选择做这道菜时,它本身对于我们的总和是负增加。有的人肯定想了,那还不简单,那我不选它不就行了吗。不!选了满意值为负数也有可能增大总和。
我们先从最简单的情况思考:如果我们只能选一道题,我们会怎么选?肯定大家会想到去选一道满意程度最大的菜s1,而且我们还得验证s1是否大于0,否则我们增大总和。
此时的总和W:
然后我们又可以再选一道菜,这时我们选了满意程度第二的s2,那么此时的总和是多少呢?
此时的总和W:
如何知道我们什么条件下我们的总和增加了,也就是W2>W1,我们通过简单的数学推导就可以知道当时W2是大于W1的。也就是说如果s1+s2>0的话我们就可以选择s2这道题,这样可以让W变大,而我们所做的一切正是为了让W变大。
如果我们此时还可以选择第三道菜:我们会选择满意程度第三的菜s3,那么此时的总和将会是:,为了确保W3>W2,我们推导出需要满足的条件,到这相信大家就有了一个大概的贪心思路。
1.我们需要对数组排序,这是因为我们肯定优先考虑满意程度高的菜
2.我们是否选择这道菜的标准在于:它的满意程度与前面已做的菜满意程度相加之和是否大于0,如果大于0说明即使这道菜的满意程度是负数,它也可以增加我们的总和。否则我们就不用考虑了,此时已有的总和就是最终的总和了。
🌸代码活现:
class Solution { public int maxSatisfaction(int[] satisfaction) { Arrays.sort(satisfaction); //用来统计已选的菜满意程度之和,当加入一道菜后sum为正数,说明它可以增大我们的总和count int sum=0; int n=satisfaction.length; //用来统计答案的总和,每次判断到一道菜可以选择,我们就让count加上一个sum //为什么呢?因为仔细观察,每选入一道菜,此时的count加上sum就是我们需要的新count int count=0; //下标索引 int pre=n-1; while(pre>=0&&sum>=0){ sum+=satisfaction[pre--]; if(sum>0){ count+=sum; } } return count; } }
这道题的标签还有动规的做法,虽然我看不太出来哈哈哈,但困难标签的动规题代码又多复杂可想而知。由此也能看出贪心的强大之处,这代码量就和简单题差不多。