【C++动态规划 离散化】1626. 无矛盾的最佳球队|2027

本文涉及知识点

C++动态规划 离散化

LeetCode1626. 无矛盾的最佳球队

假设你是球队的经理。对于即将到来的锦标赛,你想组合一支总体得分最高的球队。球队的得分是球队中所有球员的分数 总和 。
然而,球队中的矛盾会限制球员的发挥,所以必须选出一支 没有矛盾 的球队。如果一名年龄较小球员的分数 严格大于 一名年龄较大的球员,则存在矛盾。同龄球员之间不会发生矛盾。
给你两个列表 scores 和 ages,其中每组 scores[i] 和 ages[i] 表示第 i 名球员的分数和年龄。请你返回 所有可能的无矛盾球队中得分最高那支的分数 。
示例 1:
输入:scores = [1,3,5,10,15], ages = [1,2,3,4,5]
输出:34
解释:你可以选中所有球员。
示例 2:
输入:scores = [4,5,6,5], ages = [2,1,2,1]
输出:16
解释:最佳的选择是后 3 名球员。注意,你可以选中多个同龄球员。
示例 3:
输入:scores = [1,2,3,5], ages = [8,9,10,1]
输出:6
解释:最佳的选择是前 3 名球员。
提示:
1 <= scores.length, ages.length <= 1000
scores.length == ages.length
1 <= scores[i] <= 106
1 <= ages[i] <= 1000

动态规划+离散化

将分数离散化,并用nums记录原始分数。分数最小的位1,次小的为2 ⋯ \cdots
将年龄离散化,方便处理比当前队员年龄小的队员。

动态规划的状态表示

dp[i][j] 表示 球员的年龄 <= i,离散化后的能力 <=j 组成的无矛盾球队的最大得分。空间复杂度:O(nm) m是离散后的最大年龄

动态规划的填表顺序

将任意最优解,按如下方式排序后,仍然是最优解。
一,年龄小的在前,年龄大的在后。
二,年龄相等,能力小的在前,能力大的在后。
三,年龄能力都相等,按scores中的顺序。
indexs的球员的下标按上述方式排序,按k:indexs顺序处理各球员。

动态规划的转移方程

i = ages[k] j = scores[k]
d p [ i ] [ j ] = M a x { d p [ i ] [ j ] + 当前球员的能力 前一个球员年龄相同 d p [ i − 1 ] [ j ] + 当前球员的能力 前一个球员年龄不同 dp[i][j]=Max\begin{cases} dp[i][j]+当前球员的能力 &&前一个球员年龄相同 \\ dp[i-1][j]+当前球员的能力 && 前一个球员年龄不同\\ \end{cases} dp[i][j]=Max{dp[i][j]+当前球员的能力dp[i1][j]+当前球员的能力前一个球员年龄相同前一个球员年龄不同
每次更新dp后,都要:

for (j =1 ; j <= N; j++) {dp[i][j] = max(dp[i][j], dp[i][j - 1]);dp[i][j] = max(dp[i][j], dp[i-1][j ]);}

时间复杂度:O(nm)

动态规划的初始值

全为0

动态规划的返回值

dp的最大值。

代码

核心代码

class Solution {public:int bestTeamScore(vector<int>& scores, vector<int>& ages) {const int N = scores.size();{auto tmp = ages;tmp.emplace_back(0);CDiscretize dis(tmp);for (auto& i : ages) {i = dis[i];}}const int M = *max_element(ages.begin(), ages.end());auto tmp = scores;tmp.emplace_back(0);CDiscretize dis(tmp);for (auto& i : scores) {i = dis[i];}vector<int> index(N);iota(index.begin(), index.end(), 0);sort(index.begin(), index.end(), [&](int i1, int i2) {return (ages[i1] < ages[i2]) || ((ages[i1] == ages[i2]) && (scores[i1] < scores[i2]));	});vector<vector<int>> dp(M + 1, vector<int>(N + 1));int ans = 0;for (int k : index) {const int i = ages[k];int j = scores[k];dp[i][j] = max(dp[i - 1][j], dp[i][j]) + dis.m_nums[j];ans = max(ans, dp[i][j]);for (j =1 ; j <= N; j++) {dp[i][j] = max(dp[i][j], dp[i][j - 1]);dp[i][j] = max(dp[i][j], dp[i-1][j ]);}}return ans;}};

单元测试

vector<int> scores, ages;TEST_METHOD(TestMethod1){scores = { 3,2,4 }, ages = { 1,2,3 };auto res = Solution().bestTeamScore(scores, ages);AssertEx(7, res);}TEST_METHOD(TestMethod11){scores = { 1,3,5,10,15 }, ages = { 1,2,3,4,5 };auto res = Solution().bestTeamScore(scores, ages);AssertEx(34, res);}TEST_METHOD(TestMethod12){scores = { 4,5,6,5 }, ages = { 2,1,2,1 };auto res = Solution().bestTeamScore(scores, ages);AssertEx(16, res);}TEST_METHOD(TestMethod13){scores = { 1,2,3,5 }, ages = { 8,9,10,1 };auto res = Solution().bestTeamScore(scores, ages);AssertEx(6, res);}TEST_METHOD(TestMethod14){scores = { 1,1,1 }, ages = { 3,2,1 };auto res = Solution().bestTeamScore(scores, ages);AssertEx(3, res);}TEST_METHOD(TestMethod15){scores = { 1,1,1 }, ages = { 1,3,5};auto res = Solution().bestTeamScore(scores, ages);AssertEx(3, res);}TEST_METHOD(TestMethod16){scores = { 1,1,1,1,1,1,1,1,1,1 }, ages = { 811,364,124,873,790,656,581,446,885,134 };auto res = Solution().bestTeamScore(scores, ages);AssertEx(10, res);}TEST_METHOD(TestMethod17){scores = { 6,5,1,7,6,5,5,4,10,4 }, ages = { 3,2,5,3,2,1,4,4,5,1 };auto res = Solution().bestTeamScore(scores, ages);AssertEx(43, res);}

优化

i1 < i2 ,k1 = index[i1] ,k2 = index[i2]。
某方案以球员k1结尾。
如果k1的能力小于等于k2,则此方案加上i2一定不会冲突。
如果 k1的能了大于k2,由于已经按本题解排序,所以k1的年龄一定小于k2:故一定冲突。
故只需枚举能力小于等于当前能力的球员。空间复杂度:O(n)
可以用线段树。时间复杂度:O(nlogn)
直接枚举时间复杂度:O(nn)

代码

class CDiscretize //离散化
{
public:CDiscretize(vector<int> nums){sort(nums.begin(), nums.end());nums.erase(std::unique(nums.begin(), nums.end()), nums.end());m_nums = nums;for (int i = 0; i < nums.size(); i++){m_mValueToIndex[nums[i]] = i;}}int operator[](const int value)const{auto it = m_mValueToIndex.find(value);if (m_mValueToIndex.end() == it){return -1;}return it->second;}int size()const{return m_mValueToIndex.size();}vector<int> m_nums;
protected:	unordered_map<int, int> m_mValueToIndex;
};class Solution {public:int bestTeamScore(vector<int>& scores, vector<int>& ages) {const int N = scores.size();			CDiscretize dis(scores);for (auto& i : scores) {i = dis[i];}vector<int> index(N);iota(index.begin(), index.end(), 0);sort(index.begin(), index.end(), [&](int i1, int i2) {return (ages[i1] < ages[i2]) || ((ages[i1] == ages[i2]) && (scores[i1] < scores[i2]));	});vector<int> dp(N + 1);int ans = 0;for (int k : index) {const int i = ages[k];int j = scores[k];const int iMax = *max_element(dp.begin() , dp.begin() + j + 1);dp[j] = max(dp[j], iMax + dis.m_nums[j]);ans = max(ans, dp[j]);}return ans;}};

扩展阅读

我想对大家说的话
工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛
失败+反思=成功 成功+反思=成功

视频课程

先学简单的课程,请移步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.mzph.cn/web/67621.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSS 值和单位详解:从基础到实战

CSS 值和单位详解&#xff1a;从基础到实战 1. 什么是 CSS 的值&#xff1f;示例代码&#xff1a;使用颜色关键字和 RGB 函数 2. 数字、长度和百分比2.1 长度单位绝对长度单位相对长度单位 2.2 百分比 3. 颜色3.1 颜色关键字3.2 十六进制 RGB 值3.3 RGB 和 RGBA 值3.4 HSL 和 H…

Privacy Eraser,电脑隐私的终极清除者

Privacy Eraser 是一款专为保护用户隐私而设计的全能型软件&#xff0c;它不仅能够深度清理计算机中的各类隐私数据&#xff0c;还提供了多种系统优化工具&#xff0c;帮助用户提升设备的整体性能。通过这款软件&#xff0c;用户可以轻松清除浏览器历史记录、缓存文件、Cookie、…

Android 启动流程

一 Bootloader 阶段 在嵌入式系统中&#xff0c;Bootloader的引导过程与传统的PC环境有所不同&#xff0c;主要是因为嵌入式系统的硬件配置和应用场景更加多样化。以下是嵌入式系统中Bootloader被引导的一般流程&#xff1a; 1. 硬件复位 当嵌入式设备上电或复位时&#xff…

【数据结构与算法】AVL树的插入与删除实现详解

文章目录 前言Ⅰ. AVL树的定义Ⅱ. AVL树节点的定义Ⅲ. AVL树的插入Insert一、节点的插入二、插入的旋转① 新节点插入较高左子树的左侧&#xff08;左左&#xff09;&#xff1a;右单旋② 新节点插入较高右子树的右侧&#xff08;右右&#xff09;&#xff1a;左单旋③ 新节点插…

SCRM开发为企业提供全面客户管理解决方案与创新实践分享

内容概要 在当今的商业环境中&#xff0c;客户关系管理&#xff08;CRM&#xff09;变得越来越重要。而SCRM&#xff08;社交客户关系管理&#xff09;作为一种新兴的解决方案&#xff0c;正在帮助企业彻底改变与客户的互动方式。快鲸SCRM是一个引人注目的工具&#xff0c;它通…

AI应用部署——streamlit

如何把项目部署到一个具有公网ip地址的服务器上&#xff0c;让他人看到&#xff1f; 可以利用 streamlit 的社区云免费部署 1、生成requirements.txt文件 终端输入pip freeze > requirements.txt即可 requirements.txt里既包括自己安装过的库&#xff0c;也包括这些库的…

【C/C++】区分0、NULL和nullptr

&#x1f984;个人主页:小米里的大麦-CSDN博客 &#x1f38f;所属专栏:C_小米里的大麦的博客-CSDN博客 &#x1f381;代码托管:C: 探索C编程精髓&#xff0c;打造高效代码仓库 (gitee.com) ⚙️操作环境:Visual Studio 2022 目录 1. 0 和空指针 2. NULL 3. nullptr 总结 …

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】2.1 NumPy高级索引:布尔型与花式索引的底层原理

2.1 NumPy高级索引&#xff1a;布尔型与花式索引的底层原理 目录 #mermaid-svg-NpcC75NxxU2mkB3V {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-NpcC75NxxU2mkB3V .error-icon{fill:#552222;}#mermaid-svg-NpcC75…

云原生(五十二) | DataGrip软件使用

文章目录 DataGrip软件使用 一、DataGrip基本使用 二、软件界面介绍 三、附件文件夹到项目中 四、DataGrip设置 五、SQL执行快捷键 DataGrip软件使用 一、DataGrip基本使用 1. 软件界面介绍 2. 附加文件夹到项目中【重要】 3. DataGrip配置 快捷键使用&#xff1a;C…

【Elasticsearch】match_bool_prefix 查询 vs match_phrase_prefix 查询

Match Bool Prefix Query vs. Match Phrase Prefix Query 在 Elasticsearch 中&#xff0c;match_bool_prefix 查询和 match_phrase_prefix 查询虽然都支持前缀匹配&#xff0c;但它们的行为和用途有所不同。以下是它们之间的主要区别&#xff1a; 1. match_bool_prefix 查询…

算法基础——存储

引入 基础理论的进步&#xff0c;是推动技术实现重大突破&#xff0c;促使相关领域的技术达成跨越式发展的核心。 在发展日新月异的大数据领域&#xff0c;基础理论的核心无疑是算法。不管是技术设计&#xff0c;还是工程实践&#xff0c;都必须仰仗相关算法的支持&#xff0…

正则表达式入门

入门 1、提取文章中所有的英文单词 //1&#xff0e;先创建一个Pattern对象&#xff0c;模式对象&#xff0c;可以理解成就是一个正则表达式对象 Pattern pattern Pattern.compile("[a-zA-Z]"); //2&#xff0e;创建一个匹配器对象 //理解:就是 matcher匹配器按照p…

分布式架构中的事务管理:需要了解的常见解决方案

前言 在现代互联网应用中&#xff0c;分布式架构越来越常见。随着系统规模的扩大&#xff0c;越来越多的业务和数据被分布到不同的服务和数据库中。虽然分布式架构带来了诸多优势&#xff0c;但也引入了一个新的问题&#xff1a;分布式事务。 一、什么是分布式事务&#xff1…

《TCP 网络编程实战:开发流程、缓冲区原理、三次握手与四次挥手》

一、 TCP 网络应用程序开发流程 学习目标 能够知道TCP客户端程序的开发流程1. TCP 网络应用程序开发流程的介绍 TCP 网络应用程序开发分为: TCP 客户端程序开发TCP 服务端程序开发说明: 客户端程序是指运行在用户设备上的程序 服务端程序是指运行在服务器设备上的程序,专门…

新年新挑战:如何用LabVIEW开发跨平台应用

新的一年往往伴随着各种新的项目需求&#xff0c;而跨平台应用开发无疑是当前备受瞩目的发展趋势。在众多开发工具中&#xff0c;LabVIEW 以其独特的图形化编程方式和强大的功能&#xff0c;为开发跨平台应用提供了有效的途径。本文将深入探讨如何运用 LabVIEW 开发能够在不同操…

C 语言实现计算一年中指定日期是第几天 题】

引言 在编程的世界里&#xff0c;处理日期和时间相关的问题是非常常见的。比如在日历应用、任务管理系统、数据分析等场景中&#xff0c;经常需要计算某个日期在一年中是第几天。本文将详细介绍如何使用 C 语言来实现这一功能&#xff0c;通过分析代码的结构、逻辑以及可能存在…

rsync安装与使用-linux015

使用 rsync 可以非常高效地将文件或目录从一个服务器传输到另一个服务器。 能力&#xff1a; 支持 64 位文件、64 位 inode、64 位时间戳、64 位长整型支持套接字对、符号链接、符号链接时间、硬链接、硬链接特殊文件、硬链接符号链接支持 IPv6、访问时间&#xff08;atimes&…

UE5.3 C++ CDO的初步理解

一.UObject UObject是所有对象的基类&#xff0c;往上还有UObjectBaseUtility。 注释&#xff1a;所有虚幻引擎对象的基类。对象的类型由基于 UClass 类来定义。 这为创建和使用UObject的对象提供了 函数&#xff0c;并且提供了应在子类中重写的虚函数。 /** * The base cla…

Pandas基础06(异常值的检测与过滤/抽样/常用聚合函数/数据聚合)

Pandas基础06 异常值的检测与过滤 在数据分析中&#xff0c;异常值&#xff08;Outliers&#xff09;是指与其他数据点显著不同的值。这些值可能由于数据录入错误、设备故障或极端情况而产生&#xff0c;因此在进行数据分析之前&#xff0c;需要对其进行检测与过滤。本文将介绍…

【PyTorch】4.张量拼接操作

个人主页&#xff1a;Icomi 在深度学习蓬勃发展的当下&#xff0c;PyTorch 是不可或缺的工具。它作为强大的深度学习框架&#xff0c;为构建和训练神经网络提供了高效且灵活的平台。神经网络作为人工智能的核心技术&#xff0c;能够处理复杂的数据模式。通过 PyTorch&#xff0…