【动态规划】【C++算法】1340. 跳跃游戏 V

作者推荐

【动态规划】【字符串】【表达式】2019. 解出数学表达式的学生分数

本文涉及知识点

动态规划汇总

LeetCode1340跳跃游戏 V

给你一个整数数组 arr 和一个整数 d 。每一步你可以从下标 i 跳到:
i + x ,其中 i + x < arr.length 且 0 < x <= d 。
i - x ,其中 i - x >= 0 且 0 < x <= d 。
除此以外,你从下标 i 跳到下标 j 需要满足:arr[i] > arr[j] 且 arr[i] > arr[k] ,其中下标 k 是所有 i 到 j 之间的数字(更正式的,min(i, j) < k < max(i, j))。
你可以选择数组的任意下标开始跳跃。请你返回你 最多 可以访问多少个下标。
请注意,任何时刻你都不能跳到数组的外面。
示例 1:
输入:arr = [6,4,14,6,8,13,9,7,10,6,12], d = 2
输出:4
解释:你可以从下标 10 出发,然后如上图依次经过 10 --> 8 --> 6 --> 7 。
注意,如果你从下标 6 开始,你只能跳到下标 7 处。你不能跳到下标 5 处因为 13 > 9 。你也不能跳到下标 4 处,因为下标 5 在下标 4 和 6 之间且 13 > 9 。
类似的,你不能从下标 3 处跳到下标 2 或者下标 1 处。
示例 2:
输入:arr = [3,3,3,3,3], d = 3
输出:1
解释:你可以从任意下标处开始且你永远无法跳到任何其他坐标。
示例 3:
输入:arr = [7,6,5,4,3,2,1], d = 1
输出:7
解释:从下标 0 处开始,你可以按照数值从大到小,访问所有的下标。
示例 4:
输入:arr = [7,1,7,1,7,1], d = 2
输出:2
示例 5:
输入:arr = [66], d = 1
输出:1
提示:
1 <= arr.length <= 1000
1 <= arr[i] <= 105
1 <= d <= arr.length

动态规划

动态规划的状态表示

dp[i] 表示以arr[i]为起点的最多跳跃次数。

动态规划的转移方程

以左跳为例
dp[i]=max(dp[j]+1),j的范围 { 初始值: i − 1 合法值,非法则停止: ( j > = 0 ) 且 ( i − j ) < = d 且 a r r [ i ] > a r r [ j ] 增量 : j − − \begin{cases}初始值:& i-1\\ 合法值,非法则停止:& (j>=0)且(i-j)<=d 且arr[i] > arr[j] \\ 增量: &j-- \\ \end{cases} 初始值:合法值,非法则停止:增量:i1(j>=0)(ij)<=darr[i]>arr[j]j

动态规划的初始值

全为1。

动态规划的填表顺序

arr[i]从小大到

动态规划的返回值

dp的最大值

鸡肋的优化

无论是左跳还是右跳,都只会跳到能跳的最高。但最高可能有多个。比如:
33 1 2 3 左跳到第一个3就无法再跳了。

代码

核心代码

class Solution {
public:int maxJumps(vector<int>& arr, int d) {multimap<int, int> mValueIndex;for (int i = 0; i < arr.size(); i++){mValueIndex.emplace(arr[i], i);}vector<int> dp(arr.size(), 1);for (const auto& [tmp, i] : mValueIndex){for (int j = i - 1; (j >= 0) && (i - j <= d) && (arr[i] > arr[j]); j--){dp[i] = max(dp[i], 1 + dp[j]);}for (int j = i + 1; (j < arr.size()) && (j-i <= d) && (arr[i] > arr[j]); j++){dp[i] = max(dp[i], 1 + dp[j]);}}return *std::max_element(dp.begin(), dp.end());}
};

测试用例

template<class T>
void Assert(const T& t1, const T& t2)
{assert(t1 == t2);
}template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{if (v1.size() != v2.size()){assert(false);return;}for (int i = 0; i < v1.size(); i++){Assert(v1[i], v2[i]);}}int main()
{	vector<int> arr;int d;{Solution sln;arr = { 66 }, d = 1;auto res = sln.maxJumps(arr, d);Assert(1, res);}{Solution sln;arr = { 6, 4, 14, 6, 8, 13, 9, 7, 10, 6, 12 }, d = 2;auto res = sln.maxJumps(arr, d);Assert(4, res);}{Solution sln;arr = { 3,3,3,3 }, d = 2;auto res = sln.maxJumps(arr, d);Assert(1, res);}{Solution sln;arr = { 7, 6, 5, 4, 3, 2, 1 }, d = 1;auto res = sln.maxJumps(arr, d);Assert(7, res);}{Solution sln;arr = { 7, 1, 7, 1, 7, 1 }, d = 2;auto res = sln.maxJumps(arr, d);Assert(2, res);}}

2023年2月

class Solution {
public:
int maxJumps(vector& arr, int d) {
m_iNums.assign(arr.size(), -1);
m_vJumpPos.resize(arr.size());
LeftJumpPos(m_vJumpPos, arr, d);
RightJumpPos(m_vJumpPos,arr, d);
for (int i = 0; i < arr.size(); i++)
{
Rec(i);
}
//CConsole::Out(m_vJumpPos, “|”);
//CConsole::Out(m_iNums, “|”);
return *std::max_element(m_iNums.begin(),m_iNums.end());
}
int Rec(int iPos)
{
if (-1 != m_iNums[iPos])
{
return m_iNums[iPos];
}
int iMaxNextNum = 0;
for (const auto& i : m_vJumpPos[iPos])
{
iMaxNextNum = max(iMaxNextNum, Rec(i));
}
return m_iNums[iPos] = iMaxNextNum + 1;
}
vector m_iNums;
void LeftJumpPos(vector<vector>& vLeftJumpPos,const vector& arr, int d)
{
vector vLeftIndexs, vLeftValue;
int iHasDo = 0;
for (int i = 0; i < arr.size(); i++)
{
while ((iHasDo < vLeftIndexs.size()) && (vLeftIndexs[iHasDo] + d < i))
{
iHasDo++;
}
auto it = std::upper_bound(vLeftValue.begin() + iHasDo, vLeftValue.end(), arr[i], std::greater());
if (vLeftValue.end() == it)
{
}
else
{
for (auto ij = it; (ij != vLeftValue.end()) && (*it == *ij); ++ij)
{
int index = ij - vLeftValue.begin();
vLeftJumpPos[i].push_back(vLeftIndexs[index]);
}
}
while ((vLeftValue.size() > iHasDo) && (arr[i] > vLeftValue.back()))
{
vLeftIndexs.pop_back();
vLeftValue.pop_back();
}
vLeftIndexs.push_back(i);
vLeftValue.push_back(arr[i]);
}
}
void RightJumpPos(vector<vector>& vJumpPos, const vector& arr, int d)
{
vector vIndexs, vValue;
int iHasDo = 0;
for (int i = arr.size() - 1; i >= 0; i–)
{
while ((iHasDo < vIndexs.size()) && (vIndexs[iHasDo] - d > i))
{
iHasDo++;
}
auto it = std::upper_bound(vValue.begin() + iHasDo, vValue.end(), arr[i], std::greater());
if (vValue.end() == it)
{
}
else
{
for (auto ij = it; (ij != vValue.end()) && (*it == *ij);++ij)
{
int index = ij - vValue.begin();
vJumpPos[i].push_back(vIndexs[index]);
}
}
while ((vValue.size() > iHasDo) && (arr[i] > vValue.back()))
{
vIndexs.pop_back();
vValue.pop_back();
}
vIndexs.push_back(i);
vValue.push_back(arr[i]);
}
}
vector<vector> m_vJumpPos;
};

2023年7月版

class Solution {
public:
int maxJumps(vector& arr, int d) {
m_c = arr.size();
m_d = d;
vector<vector> vLeft,vRight,vMove(m_c);
GetLeft(vLeft, arr);
GetRight(vRight, arr);
for (int i = 0; i < m_c; i++)
{
vMove[i].insert(vMove[i].end(), vLeft[i].begin(), vLeft[i].end());
const int right = m_c - 1 - i;
vMove[i].insert(vMove[i].end(), vRight[right].begin(), vRight[right].end());
}
//值从小到大出来
std::multimap<int, int> mValueIndexs;
for (int i = 0; i < arr.size(); i++)
{
mValueIndexs.emplace(arr[i], i);
}
vector vRet(m_c, -1);
for (const auto& it : mValueIndexs)
{
int iCanMove = 0;
for (const auto& next : vMove[it.second])
{
iCanMove = max(iCanMove, vRet[next]);
}
vRet[it.second] = iCanMove+1;
}
return *std::max_element(vRet.begin(), vRet.end());
}
void GetLeft(vector<vector>& vMove, const vector& arr)
{
std::stack sta;
for (int i = 0; i < arr.size(); i++)
{
int iMoveValue = -1;
vMove.emplace_back();
while (sta.size() && (arr[sta.top()] < arr[i]))
{
const int iTop = sta.top();
sta.pop();
if (abs(iTop - i) <= m_d)
{
if (arr[iTop] != iMoveValue)
{
vMove.back().clear();
}
vMove.back().emplace_back(iTop);
iMoveValue = arr[iTop];
}
}
sta.emplace(i);
}
}
void GetRight(vector<vector>& vMove, const vector& arr)
{
std::stack sta;
for (int i = m_c - 1; i >= 0; i–)
{
int iMoveValue = -1;
vMove.emplace_back();
while (sta.size() && (arr[sta.top()] < arr[i]))
{
const int iTop = sta.top();
sta.pop();
if (abs(iTop - i) <= m_d)
{
if (arr[iTop] != iMoveValue)
{
vMove.back().clear();
}
vMove.back().emplace_back(iTop);
iMoveValue = arr[iTop];
}
}
sta.emplace(i);
}
}
int m_c;
int m_d;
};

2023年8月版

class Solution {
public:
int maxJumps(vector& arr, int d) {
m_c = arr.size();
m_arr = arr;
m_iD = d;
m_vCanMove.resize(m_c);
DoLeft();
DoRight();
std::multimap<int, int> mHeightIndex;
for ( int i = 0; i < m_c; i++)
{
mHeightIndex.emplace(arr[i], i);
}
vector vRet(m_c);
for (const auto& it : mHeightIndex)
{
int iPre = 0;
for (const int pr : m_vCanMove[it.second])
{
iPre = max(iPre, vRet[pr]);
}
vRet[it.second] = iPre + 1;
}
return *std::max_element(vRet.begin(), vRet.end());
}
void DoLeft()
{
stack sta;
for (int i = 0; i < m_c; i++)
{
vector vCanMove;
while (sta.size() && (m_arr[sta.top()] < m_arr[i]))
{
if (abs(sta.top() - i) <= m_iD)
{
vCanMove.emplace_back(sta.top());
}
sta.pop();
}
if (vCanMove.size())
{
const int iMax = m_arr[vCanMove.back()];
for (int j = vCanMove.size() - 1; (j >= 0)&&(iMax == m_arr[vCanMove[j]]); j–)
{
m_vCanMove[i].emplace_back(vCanMove[j]);
}
}
sta.emplace(i);
}
}
void DoRight()
{
stack sta;
for (int i = m_c-1 ; i >= 0 ; i–)
{
vector vCanMove;
while (sta.size() && (m_arr[sta.top()] < m_arr[i]))
{
if (abs(sta.top() - i) <= m_iD)
{
vCanMove.emplace_back(sta.top());
}
sta.pop();
}
if (vCanMove.size())
{//只需要考虑移动到次高,如果有多个次高可以一定,全部要考虑
const int iMax = m_arr[vCanMove.back()];
for (int j = vCanMove.size() - 1; (j >= 0) && (iMax == m_arr[vCanMove[j]]); j–)
{
m_vCanMove[i].emplace_back(vCanMove[j]);
}
}
sta.emplace(i);
}
}
vector<vector> m_vCanMove;
vector m_arr;
int m_iD;
int m_c;
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

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

相关下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/249853.html

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

相关文章

git修改密码后mac使用sourceTree出现Authentication failed错误

1、退出sourceTree 2、在钥匙串中删除git对应站点Access Key 3、执行命令&#xff1a;git config --system --unset credential.helper 4、重新启动sourceTree&#xff0c;这时会弹出输入密码框&#xff0c;重新输入密码即可

数据库管理-第141期 DG PDB - Oracle DB 23c(20240129)

数据库管理141期 2024-01-29 第141期 DG PDB - Oracle DB 23c&#xff08;20240129&#xff09;1 概念2 环境说明3 操作3.1 数据库配置3.2 配置tnsname3.3 配置强制日志3.4 DG配置3.5 DG配置建立联系3.6 启用所有DG配置3.7 启用DG PDB3.8 创建源PDB的DG配置3.9 拷贝pdbprod1文件…

CSS实现文字大小自适应

遇到的问题&#xff1a; 在写页面的时候&#xff0c;兼容手机和PC页面&#xff0c;这样字体大小就需要根据页面的大小进行动态变化。 解决方法&#xff1a; clamp()函数 clamp() 函数的作用是把一个值限制在一个上限和下限区间&#xff0c;当这个值超过区间范围时&#xff0c;…

(学习日记)2024.02.01:引用变量 / 默认实参 / 一元作用域运算符 / 函数重载

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

RabbitMQ面试

1. 什么是消息中间件 消息中间件是在分布式系统中传递消息的软件服务。它允许不同的系统组件之间通过消息进行通信&#xff0c;而无需直接连接到彼此。消息中间件通常用于解耦系统的各个部分&#xff0c;提高系统的可扩展性、灵活性和可维护性。 2. 消息中间件解决了什么问题…

TCP/IP网络模型

大家好我是苏麟 , 今天聊聊TCP/IP四层网络模型 . 资料来源 : 小林coding 小林官方网站 : 小林coding (xiaolincoding.com) 应用层 最上层的&#xff0c;也是我们能直接接触到的就是应用层&#xff08;Application Layer&#xff09;&#xff0c;我们电脑或手机使用的应用软件都…

初始MySQL

一 SQL的基本概述 基本概述 ▶SQL全称: Structured Query Language&#xff0c;是结构化查询语言&#xff0c;用于访问和处理数据库的标准的计算机语言。SQL语言1974年由Boyce和Chamberlin提出&#xff0c;并首先在IBM公司研制的关系数据库系统SystemR上实现。 ▶美国国家标…

JMeter 下载、安装、启动

JMeter安装部署依赖Java环境&#xff0c;所以首先得安装JDK。 JDK下载JDK环境变量配置 ① 新建系统环境变量JAVA_HOME ② 编辑系统变量Path ③ 新建系统变量CLASSPATH变量 JMeter下载安装 Apache JMeter - Apache JMeter™ JMeter安装部署依赖Java环境&#xff0c;所以首…

降维(Dimensionality Reduction)

一、动机一&#xff1a;数据压缩 这节我将开始谈论第二种类型的无监督学习问题&#xff0c;称为降维。有几个原因使我们可能想要做降维&#xff0c;其一是数据压缩&#xff0c;它不仅允许我们压缩数据使用较少的计算机内存或磁盘空间&#xff0c;而且它可以加快我们的学习算法。…

【2024美赛E题】985博士解题思路分析(持续更新中)!

【2024美赛E题】985博士解题思路分析&#xff01; 加群可以享受定制等更多服务&#xff0c;或者搜索B站&#xff1a;数模洛凌寺 联络组织企鹅&#xff1a;936670395 以下是E题老师的解题思路&#xff08;企鹅内还会随时更新文档&#xff09;&#xff1a; 2024美赛E题思路详解…

蓝桥杯2024/1/31----第十届省赛题笔记

题目要求&#xff1a; 1、 基本要求 1.1 使用大赛组委会提供的国信长天单片机竞赛实训平台&#xff0c;完成本试题的程序设计 与调试。 1.2 选手在程序设计与调试过程中&#xff0c;可参考组委会提供的“资源数据包”。 1.3 请注意&#xff1a; 程序编写、调试完成后选手…

没有外网Nginx如何配置如何开启https

判断是否支持open-ssl 在服务器执行如下命令 openssl version没有则安装open-ssl&#xff0c;由于服务器没有外网&#xff0c;可以离线安装openssl-3.0.1.tar.gz&#xff0c;我是在有网的服务器直接下载的&#xff0c;然后再上传到这台无网的服务器上 wget https://www.open…

React实现组件扩展机制

在java中&#xff0c;SPI机制是Java中提供的一种服务发现机制。同样&#xff0c;前端也很需要这种机制&#xff0c;这样可以做到组件可插拔&#xff0c;可替换&#xff0c;减少相互冗余。 快速使用 1.扩展点使用 通过使用Extension组件定义扩展点&#xff0c;通过name标记扩展…

Facebook的创新征程:社交媒体的演进之路

在当今数字化时代&#xff0c;社交媒体已经成为人们生活中不可或缺的一部分&#xff0c;而Facebook作为社交媒体领域的巨头&#xff0c;一直在不断创新和演进。本文将深入探讨Facebook的创新征程&#xff0c;追溯其社交媒体的发展历程&#xff0c;探讨其对用户、社会和数字时代…

巨人踏步,港口自动驾驶提速向前打开行业新空间

按照吞吐量排名&#xff0c;全世界最大的50个港口&#xff0c;中国占了29个。在中国的港口和码头上&#xff0c;一场进化正在发生&#xff1a;人在这个生态中占的比重越来越少&#xff0c;技术接管的要素正在越来越多。像是最具代表性的全球综合自动化程度最高的码头——上海洋…

12nm工艺,2.5GHz频率,低功耗Cortex-A72处理器培训

“ 12nm工艺&#xff0c;2.5GHz频率&#xff0c;低功耗Cortex-A72处理器培训” 本项目是真实项目实战培训&#xff0c;低功耗UPF设计&#xff0c;后端参数如下&#xff1a; 工艺&#xff1a;12nm 频率&#xff1a;2.5GHz 资源&#xff1a;2000_0000 instances 为了满足更多…

k8s二进制及负载均衡集群部署详解

目录 常见部署方式 二进制部署流程 环境准备 操作系统初始化配置 关闭防火墙 配置SELinux 关闭SWAP 根据规划设置主机名 在master添加hosts&#xff0c;便于主机名解析 调整内核参数 配置时间同步 部署docker引擎 在所有node节点部署docker引擎 部署etcd集群 签发…

Sentinel 知识总结

Sentinel 知识总结 Sentinel 是阿里巴巴开源的一个轻量级流量控制框架&#xff0c;主要用于保护系统稳定性和流畅性。它提供了多种流量控制策略&#xff0c;包括QPS限流、并发数限流、线程池限流等&#xff0c;并且支持集群限流。此外&#xff0c;Sentinel还提供了熔断降级、系…

51单片机编程应用(C语言):数码管

目录 1.数码管原理 一位数码管引脚定义&#xff1a; 四位一体数码管&#xff1a; 多个数码管同时显示不同数字 51单片机的数码管的原理图 51单片机实现静态显示和动态显示 静态显示&#xff1a; 动态显示&#xff1a; 1.数码管原理 一位数码管引脚定义&#xff1a; 数码…

Git版本管理工具(实战进阶):零基础到起飞实战项目完整篇 →Git学习一篇就够 从基本指令、到本地仓库、远程仓库、实战项目开发演练介绍超详细!

heima 李师傅最新版 Git的讲解 文章目录 Git在实战项目开发使用功能学习01.Git 初识02.Git 仓库03.Git 的三个区域04.Git 文件状态05.Git 暂存区作用06.练习-登录页面07.Git-切换版本08.删除文件09.忽略文件10.分支的概念11.练习-登录 bug 修复12.分支-合并与删除13.分支-合并与…