每天睡前是否感到浑浑噩噩,一天又在不知不觉中过去,回想我今天都干了什么呢?
啊~我这一天又什么也没干,好有罪恶感啊,不行,我明天一定要好好学算法(手动狗头)。
明日复明日,明日何其多?不要等明天啦,和小编一起,每天睡前一道算法题,不仅解决你一天的空虚,更能助你安心入眠,远离熬夜。还能学到一点算法知识。不要小看这些知识哦,不积跬步无以至千里,不积小流无以成江海。每位大佬都不是一夜成名,都是从小白做起,日积月累,终成大佬,和小编一起,每日一题,走向大佬之路吧!
我们的题基本都是一些较为基础,适合日(睡)常(前)看的题,不会让你一眼就看出答案,是稍稍一点脚就能摸到头绪,但是在想的过程中又一时不知如何实现,再一想,又柳暗花明,最终跟着小编的思路一起解决问题,有不同思路可以发在评论区,一起讨论。“你若在,我必回”。
先看题目:
一个厨师收集了他 n 道菜的满意程度 satisfaction ,这个厨师做出每道菜的时间都是 1 单位时间。
一道菜的 「喜爱时间」系数定义为烹饪这道菜以及之前每道菜所花费的时间乘以这道菜的满意程度,也就是 time[i]*satisfaction[i] 。
请你返回做完所有菜 「喜爱时间」总和的最大值为多少。
你可以按 任意 顺序安排做菜的顺序,你也可以选择放弃做某些菜来获得更大的总和。
示例 1:
输入:satisfaction = [-1,-8,0,5,-9]
输出:14
解释:去掉第二道和最后一道菜,最大的喜爱时间系数和为 (-1*1 + 0*2 + 5*3 = 14) 。每道菜都需要花费 1 单位时间完成。
示例 2:输入:satisfaction = [4,3,2]
输出:20
解释:按照原来顺序相反的时间做菜 (2*1 + 3*2 + 4*3 = 20)
示例 3:输入:satisfaction = [-1,-4,-5]
输出:0
解释:大家都不喜欢这些菜,所以不做任何菜可以获得最大的喜爱时间系数。
示例 4:输入:satisfaction = [-2,5,-1,0,3,-3]
输出:35提示:
n == satisfaction.length
1 <= n <= 500
-10^3 <= satisfaction[i] <= 10^3
简单分析过后,我们首先的一个大概思路是:满意程度为正数的都要,并且根据哈夫曼树的思想,可以知道是让满意程度大的放在最后,因为权值的原因能使总值最大。
我们的方法就是将数组由大到小排序,找到那个临界值i,返回从0到i之间的“总值”。
接下来就是如何处理负数,当加入一个负数后,总值增大或减小不确定(所有正数的权值都会+1,但会增加负数)。那么如何比较加入负数后总值的大小就是本题的关键。
小编的第一想法是如果这个负数的绝对值小于等于这个数组的最大值,那么这个负数加入后就能使总值增加,否则就减少。
那么大家想一下是不是这样?熟悉的朋友一定知道,小编的第一想法大概率是错的,所以这个想法确实不是全对。那么错在哪呢?
我们的数是截止到那个小于数组最大值的那个最小负数。那么当负数的绝对值大于最大的数时,是不是一定使总值减小?当然不是,我们刚刚说过,当加入一个数后,前面的每一个数的权值都会+1,并不是只有最大值+1。
那么我们就可以直接暴力求解,把这个负数加入到数组和加入之前的数组分别求总值并比叫,如果加入后总值增大,那么就可以加入这个负数,否则结束。
这就是全局的一个想法。对于求总值的函数,数组排序,大家看代码就能理解,就不过多赘述。不懂的朋友可以在评论区留言讨论。下面是代码实现:
class Solution {
public:
int sum(vector& p,int r){
int i,ans=0;
for(i=0;i<=r;i++){
ans+=p[i]*(r-i+1);
}
return ans;
}
int maxSatisfaction(vector& satisfaction) {
sort(satisfaction.rbegin(),satisfaction.rend());
if(satisfaction[0]<0) return 0;
int i,n=satisfaction.size();
for(i=0;i
本题来自leetcode,所以对于输入和输出要求比较简单,会通过函数直接传参,结果放在return返回。
每天坚持是一件很累的事,即使很慢,但也不要停止。小编今天没时间写太多了,但也要坚持写,即使是一道很简单的题,大家一起加油!
大家记得点赞收藏,防止找不到哦。
欢迎大家订阅小编的每日一题专栏,会每天更新,都是用心准备的哦!
若有不同思路,欢迎评论区留言,看到必回,Goodnight!