【反悔堆 反悔贪心】2813. 子序列最大优雅度

ops/2024/10/4 22:29:05/

本文涉及知识点

反悔堆 反悔贪心

LeetCode 2813. 子序列最大优雅度

给你一个长度为 n 的二维整数数组 items 和一个整数 k 。
items[i] = [profiti, categoryi],其中 profiti 和 categoryi 分别表示第 i 个项目的利润和类别。
现定义 items 的 子序列 的 优雅度 可以用 total_profit + distinct_categories2 计算,其中 total_profit 是子序列中所有项目的利润总和,distinct_categories 是所选子序列所含的所有类别中不同类别的数量。
你的任务是从 items 所有长度为 k 的子序列中,找出 最大优雅度 。
用整数形式表示并返回 items 中所有长度恰好为 k 的子序列的最大优雅度。
注意:数组的子序列是经由原数组删除一些元素(可能不删除)而产生的新数组,且删除不改变其余元素相对顺序。
示例 1:
输入:items = [[3,2],[5,1],[10,1]], k = 2
输出:17
解释:
在这个例子中,我们需要选出长度为 2 的子序列。
其中一种方案是 items[0] = [3,2] 和 items[2] = [10,1] 。
子序列的总利润为 3 + 10 = 13 ,子序列包含 2 种不同类别 [2,1] 。
因此,优雅度为 13 + 22 = 17 ,可以证明 17 是可以获得的最大优雅度。
示例 2:
输入:items = [[3,1],[3,1],[2,2],[5,3]], k = 3
输出:19
解释:
在这个例子中,我们需要选出长度为 3 的子序列。
其中一种方案是 items[0] = [3,1] ,items[2] = [2,2] 和 items[3] = [5,3] 。
子序列的总利润为 3 + 2 + 5 = 10 ,子序列包含 3 种不同类别 [1, 2, 3] 。
因此,优雅度为 10 + 32 = 19 ,可以证明 19 是可以获得的最大优雅度。
示例 3:
输入:items = [[1,1],[2,1],[3,1]], k = 3
输出:7
解释:
在这个例子中,我们需要选出长度为 3 的子序列。
我们需要选中所有项目。
子序列的总利润为 1 + 2 + 3 = 6,子序列包含 1 种不同类别 [1] 。
因此,最大优雅度为 6 + 12 = 7 。

提示:
1 <= items.length == n <= 105
items[i].length == 2
items[i][0] == profiti
items[i][1] == categoryi
1 <= profiti <= 109
1 <= categoryi <= n
1 <= k <= n

反悔贪心

最大数:某个类型最大利润。
枚举类型t,分别计算最大和:
小根堆maxHeap记录各类型的最大值,大根对otherHeap记录各类型非最大值。
如果maxHeap的元素数量大于k,则出栈到k。更新结果。操作一
t = maxHeap.size()。 将otherHeap中的数,移到headMax直到maxHeap 的元素数量位k。更新结果。操作二
如果otherHeap非空,且栈顶元素大于maxHeap栈顶元素,则移动元素到maxHeap。t–,更新结果。操作三
性质一:因为是otherHeap是从大到小出栈,故不会替换来源于otherHeap的数,只会替换来源于maxHeap的数,即类型数减1。
性质二:otherHeap中的x1替换maxHeap中的数x2时,和x类型相同的最大树一定还在maxHeap中。x2在maxHeap中,说明比x2的类型最大数都在堆中。x2是最后出堆,故比x2大的数仍然没有出堆。故操作三不会增加类型。
性质三:结合性质一、性质二操作三必定让会类型减少1。
性质四:操作一出栈的数永远不会用到。操作一和操作二不会同时存在。操作三只会让maxHeap的数越大越大。即操作一出栈的数永远小于等于maxHeap中的元素。类型越来越少的情况下,和不变或变小,一定被淘汰。

数学归纳法:本方法必定找到最优解

初始状态是最大类型的最优接:
操作一后:堆中就是最大的k个最大数,显然是最后解。
操作二后:所有类型最大值都在里面。由于类型已经到达最大值,所有无法增加。只需要保证和最大。
t个类型的最优解通过操作三操作一次后必定是t-1的最优解
想让t减少1,唯一的方案:
最大值删除一个数,非最大值增加一个数。显然要删除最小值,且增加最大值,且增加的数大于删除的数。
按操作三的方法t一定会变成0。最后一个最大值一定是所有数的最大值,不会被淘汰。

好理解的方案

vMax升序记录最大值,vOther升序记录其它数。
枚举i个元素来自于vMax,其它元素来自于vOther:i ∈ \in [1,min(k,vMax.size())] 同 (k-i) >= 0 ,且(k-i) <= vOther.size()
类型为i的最大价值就是:vMax的前i个元素和+ vOther的前k-i个元素 + i2
注意: 有可能类型不为i,即vOther的前(k-i)个元素对应的最大值没有被选择,此方案的优雅度计算少了。
但此方案就算不计算少了,也会被方案二淘汰:将这些元素换成对应的最大值。
求最大值时,某个被淘汰的方案被算小了,不会影响最终结果。

代码

核心代码

class Solution {
public:long long findMaximumElegance(vector<vector<int>>& items, int k) {sort(items.begin(), items.end(), std::greater<>());unordered_set<int> setHas;priority_queue<int,vector<int>,greater<>> maxHeap;priority_queue<int> otherHeap;long long sum = 0;for (const auto& v : items) {if (setHas.count(v[1])) {otherHeap.emplace(v[0]);}else {maxHeap.emplace(v[0]);sum += v[0];setHas.emplace(v[1]);}}while (maxHeap.size() > k) {sum -= maxHeap.top();maxHeap.pop();}long long t = maxHeap.size();while (maxHeap.size() < k) {sum += otherHeap.top();maxHeap.emplace(otherHeap.top());otherHeap.pop();}long long ret = sum + t * t;for (t--; t > 0; t--) {if (otherHeap.size() && (otherHeap.top() > maxHeap.top())) {sum += otherHeap.top();sum -= maxHeap.top();maxHeap.pop();maxHeap.emplace(otherHeap.top());otherHeap.pop();ret = max(ret, sum + t * t);}}return ret;}
};

单元测试

template<class T1, class T2>
void AssertEx(const T1& t1, const T2& t2)
{Assert::AreEqual(t1, t2);
}template<class T>
void AssertEx(const vector<T>& v1, const vector<T>& v2)
{Assert::AreEqual(v1.size(), v2.size());for (int i = 0; i < v1.size(); i++){Assert::AreEqual(v1[i], v2[i]);}
}template<class T>
void AssertV2(vector<vector<T>> vv1, vector<vector<T>> vv2)
{sort(vv1.begin(), vv1.end());sort(vv2.begin(), vv2.end());Assert::AreEqual(vv1.size(), vv2.size());for (int i = 0; i < vv1.size(); i++){AssertEx(vv1[i], vv2[i]);}
}namespace UnitTest
{	vector<vector<int>>items;int k;TEST_CLASS(UnitTest){public:TEST_METHOD(TestMethod00){items = { {3,2},{5,1},{10,1} }, k = 2;auto res = Solution().findMaximumElegance(items, k);AssertEx(17LL, res);}TEST_METHOD(TestMethod01){items = { {3,1},{3,1},{2,2},{5,3} }, k = 3;auto res = Solution().findMaximumElegance(items, k);AssertEx(19LL, res);}TEST_METHOD(TestMethod02){items = { {1,1},{2,1},{3,1} }, k = 3;auto res = Solution().findMaximumElegance(items, k);AssertEx(7LL, res);}TEST_METHOD(TestMethod03){items = { {2,2},{8,3},{8,3} }, k =2;auto res = Solution().findMaximumElegance(items, k);AssertEx(17LL, res);}};
}

扩展阅读

视频课程

先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关推荐

我想对大家说的话

《喜缺全书算法册》以原理、正确性证明、总结为主。
按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
|闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。|
| 子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。 |
|如果程序是一条龙,那算法就是他的是睛|

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。


http://www.ppmy.cn/ops/55879.html

相关文章

【鸿蒙学习笔记】MVVM模式

官方文档&#xff1a;MVVM模式 [Q&A] 什么是MVVM ArkUI采取MVVM Model View ViewModel模式。 Model层&#xff1a;存储数据和相关逻辑的模型。View层&#xff1a;在ArkUI中通常是Component装饰组件渲染的UI。ViewModel层&#xff1a;在ArkUI中&#xff0c;ViewModel是…

机器学习:预测评估8类指标

机器学习&#xff1a;8类预测评估指标 R方值、平均值绝对误差值MAE、均方误差MSE、均方误差根EMSE、中位数绝对误差MAD、平均绝对百分误差MAPE、可解释方差分EVS、均方根对数误差MLSE。 一、R方值 1、说明&#xff1a; R方值&#xff0c;也称为确定系数或拟合优度&#xff…

Gemma2——Google 新开源大型语言模型完整应用指南

0.引言 Gemma 2以前代产品为基础&#xff0c;提供增强的性能和效率&#xff0c;以及一系列创新功能&#xff0c;使其在研究和实际应用中都具有特别的吸引力。Gemma 2 的与众不同之处在于&#xff0c;它能够提供与更大的专有模型相当的性能&#xff0c;但其软件包专为更广泛的可…

第一节 网络安全概述

一.网络空间安全 网络空间&#xff1a;一个由信息基础设施组成相互依赖的网络。 ---- 海陆空天&#xff08;大海、陆 地、天空、航天&#xff09; 通信保密阶段 ---- 计算机安全 ----- 信息系统安全 ----- 网络空间安全 计算机安全&#xff1a;开始秉持着“严于律己&#x…

GitHub Copilot API

1. 引言 GitHub Copilot&#xff1a;智能编程的革新者 在软件开发的浩瀚宇宙中&#xff0c;GitHub Copilot犹如一颗璀璨的新星&#xff0c;以其独特的魅力引领着智能编程的新纪元。作为GitHub与OpenAI合作推出的革命性工具&#xff0c;Copilot不仅仅是一个简单的代码补全插件…

QWidget窗口抗锯齿圆角的一个实现方案(支持子控件)2

QWidget窗口抗锯齿圆角的一个实现方案&#xff08;支持子控件&#xff09;2 本方案使用了QGraphicsEffect&#xff0c;由于QGraphicsEffect对一些控件会有渲染问题&#xff0c;比如列表、表格等&#xff0c;所以暂时仅作为研究&#xff0c;优先其他方案 在之前的文章中&#…

CSS - 深入理解选择器的使用方式

CSS基本选择器 通配选择器元素选择器类选择器id 选择器 通配选择器 作用&#xff1a;可以选中所有HTML元素。语法&#xff1a; * {属性名&#xff1b;属性值; }举例&#xff1a; /* 选中所有元素 */ * {color: orange;font-size: 40px; }在清除样式方面有很大作用 元素选择器…

计算机专业怎么选择电脑

现在高考录取结果基本已经全部出来了&#xff0c;很多同学都如愿以偿的进入到了计算机类专业&#xff0c;现在大部分同学都在为自己的大学生活做准备了&#xff0c;其中第一件事就是买电脑&#xff0c;那计算机类专业该怎么选择电脑呢&#xff1f; 计算机专业是个一类学科&…