LeekCode第3767题选择K个任务的最大总分:详细思考过程幽默解析 专门为小白准备

hi,你们好,我是汉堡!我真的是好久没发了我去发B站了,我又回来了!今天我们来看一下 力扣第 3767题 选择K个任务的最大总分 本题是一道贪心算法题目 难度中等。本篇题解完全按照小白的思考逻辑进行思考,告诉你如何从一个初期的不完整的思路到最后优化过的正确思路。希望你能认真看完并仔细跟随我的思路思考

我这一篇写的是真不容易啊!


文章目录


题目链接

点击蓝字查看题目

没有力扣账号的注册一下


思路分析

前置分析

学过贪心的一读题就知道这是一道贪心算法的题目 其实可以查看题目的标签

我们知道:想要获得最大的总分,就要使每一次做任务时获得的分数最大(贪心的基本思想:局部最优造就全局最优 前面的c++算法------贪心策略幽默详细讲解 原来贪婪也有作用(习题持续更新)讲过)而想要每一次获得更大的分数

  • 如果第 i 个任务使用技巧 1 完成,你将获得 technique1[i] 分。
  • 如果使用技巧 2 完成,你将获得 technique2[i] 分。

根据题目的描述,想要获得最优的答案,我们要使用能获得最大分数的技巧来完成任务,简单的来说:每次完成任务,选择能获得最大分数的技巧

初步考虑

但是,你接着往下读

必须 使用技巧 1 完成 至少 k 个任务(不需要是前 k 个任务)

这时候你蒙了:如果每次选择能获得最大分数的技巧,那么不一定能够使用够k技巧 1 1 1 ,而如果先选择够k技巧 1 1 1剩下的再按照前面的规则选择,你又不知道前面的k个** 技巧 1 1 1​** 选择哪k个才能使最后获得最大的总分

浅表的想,你想到可以选择前k个最大的technique1中的元素,这样应该可以使这k个任务获得最大的分值

but(但是),我告诉你:不对!万一有那么一组数据,前k个最大的technique1元素对应的 technique2 的元素比这k个还要大,而稍微小一点的ktechnique1元素对应的 technique2 的元素比它要小(它指稍微小一点的一些technique1元素 )这时候明显选的前k个元素不符合得到最优答案的条件,而又有一种选法(刚说的)既满足题目的要求有满足获得最优答案的要求,这说明这种选法不是最优的,这个策略行不通!

深入分析

我们继续换一种思路,在刚刚举反例的过程中,我们想到了只需要选择 技巧 1 − 技巧 2 技巧1-技巧2 技巧1−技巧2的差最大的k个技巧 1 1 1​即可,剩下的再按照基本原则进行选择

举个题目中的例子分析一下

technique1 = [5,2,10], technique2 = [10,3,8], k = 2

先求出所有的technique1[i]-technique2[i],为:[-5,-1,2]

再降序排列得到:[2,-1,-5]

然后选择前k个即可,就是:[2,-1] 他们两个对应的是 technique1 的:[10,2]

最后按照基本的原则选择剩下的,就是 technique1中的5和technique2中的10 这一对,显然选择10。

得到答案 10 + 2 + 10 = 22 10+2+10=22 10+2+10=22 答案正确

疑惑解释

但是,认真思考的你提出了问题:"如果technique1[i] - technique2[i] 三个都是 -3,而k=2,随便选了两个-3,结果这两个负三对应的technique1[i]很小, technique2[i]很大,完美避开了最优,最大的分数啊!"

你是一个认真思考的人,很棒!但是你的这个质疑不对因为你怀疑我的缜密思考了!,我在想这个思路时也想到了这个问题,但是仔细一想其实不存在。

举个例子:
technique1 = [1,2,3], technique2 = [4,5,6], k = 2

这个例子就是你的"反例",我们来试一下

如果选任务1和2用技巧1,则任务3用技巧2,总分 = 1 + 2 + 6 = 9 1+2+6 = 9 1+2+6=9

如果选任务1和3,总分 = 1 + 3 + 5 = 9 1+3+5 = 9 1+3+5=9

如果选任务2和3,总分 = 2 + 3 + 4 = 9 2+3+4 = 9 2+3+4=9

答案不管如何选前k个都相同。

为啥呢?我解释一下道理:因为他们的差都相同,所以

technique1小一点的,最后的technique2会刚好补上,

technique1大一点的,最后的technique2会刚好拉低。

最后的答案还是一样的

代码实现

但是,完全模拟这个思路不太好写,technique1和technique2的差经过排序之后 和technique1、technique2对应关系都乱了,很难一一对应,并排除使用已经干过的任务,于是我们把思路做简化

所以我们这样写:

先把所有的technique2加起来,存进 a n s ans ans,并统计所有的technique1[i]-technique2[i],装进一个数组 d i f f diff diff,这里的 d i f f [ i ] diff[i] diff[i]如果非得解释出一个意思的话,就是:使用技巧1之后对最终答案的影响,是正数就是往好的影响,是负数就是往坏的影响(看到后面你就懂了)

对 d i f f diff diff进行降序排序

这时候先让 a n s ans ans累加上正的 d i f f diff diff(因为所有的technique2加起来不一定就是最优的答案(这你们看到这里也都知道)而正的 d i f f diff diff就是那些选技巧1更优的任务比选技巧2多得的分值,加上它们也就是说把这些亏的分值补上(对最终的答案做好的影响),这些任务也就最优了,当然如果加的超过了k 也不用担心,毕竟是好的影响嘛,多出去更好)

如果现在累加上的 d i f f diff diff还还不够 k k k个的话,就继续累加到第 k k k个 d i f f diff diff元素(因为,为了满足题目中的要求,我们必须使用k次技巧1,而 d i f f [ i ] diff[i] diff[i]代表的就是使用技巧1之后对最终答案的影响,也就是说,加到k就是把技巧1 使用到K次,把 d i f f diff diff加到k就是把使用技巧1之后对最终答案的影响更新(不管是好的影响还是坏的影响),而对 d i f f diff diff​进行降序排序就是为了让好的影响更多更大,尽量使用前k个的技巧1时不会出现坏的影响,即使出现也是更小的!只加到k个是因为,进到这种情况的,都是好的影响用完了,现在每多加一次都是对答案的进一步的坏影响,所以只加到k就好)
可能有点难懂,多读几遍,并结合下面的代码理解

根据这个简化的思路,实现一下代码:

cpp 复制代码
class Solution {
private:
	static bool cmp(int x, int y) {
		return x > y;
	}
public:
	long long maxPoints(vector<int>& technique1, vector<int>& technique2, int k) {
		int n = technique1.size();
		vector<int> diff(n);
		long long ans = 0;
		for (int i = 0; i < n; ++i) {
			diff[i] = technique1[i] - technique2[i];
			ans += technique2[i];
		}
		sort(diff.begin(), diff.end(), cmp);
		int posCount = 0;
		for (int i = 0; i < n && diff[i] > 0; ++i) {
			ans += diff[i];
			++posCount;
		}
		if (posCount < k) {
			for (int i = posCount; i < k; ++i) {
				ans += diff[i];
			}
		}

		return ans;
	}
};

由于这个题主要讲解思路算法,而且代码中没有出现罕见语法和一些巧妙的写法,所以不对代码进行逐句解析

最后我们通过了

总结

这个题目的思路推理我完全写进了思路分析,感谢你查看本篇题解,谢谢!

相关推荐
小白菜又菜2 小时前
Leetcode 235. Lowest Common Ancestor of a Binary Search Tree
python·算法·leetcode
We་ct2 小时前
LeetCode 222. 完全二叉树的节点个数:两种解法详解(BFS + 二分查找优化)
数据结构·算法·leetcode·typescript
小白菜又菜2 小时前
Leetcode 234. Palindrome Linked List
python·算法·leetcode
阿里云大数据AI技术2 小时前
阿里云PAI助力新一代Qwen3.5模型发布!
人工智能·算法
小白菜又菜3 小时前
Leetcode 221. Maximal Square
算法·leetcode·职场和发展
流云鹤3 小时前
牛客周赛Round 132(无F)
算法
Lee川3 小时前
深入解析:从内存模型到作用域陷阱——JavaScript变量的前世今生
javascript·算法
㓗冽3 小时前
回文数2(字符串)-基础题97th + 加法器(字符串)-基础题98th + 构造序列(字符串)-基础题99th
算法
陈天伟教授4 小时前
人工智能应用- 预测化学反应:02. 化学反应简介
人工智能·神经网络·算法·机器学习·推荐算法