当前位置: 首页 > news >正文

⭐算法OJ⭐跳跃游戏【动态规划 + 单调队列】(C++实现)Jump Game 系列 VI

⭐算法OJ⭐跳跃游戏【贪心算法】(C++实现)Jump Game 系列 I,II
⭐算法OJ⭐跳跃游戏【BFS+滑动窗口】(C++实现)Jump Game 系列 III,IIV

1696. Jump Game VI

You are given a 0-indexed integer array nums and an integer k.

You are initially standing at index 0. In one move, you can jump at most k steps forward without going outside the boundaries of the array. That is, you can jump from index i to any index in the range [i + 1, min(n - 1, i + k)] inclusive.

You want to reach the last index of the array (index n - 1). Your score is the sum of all nums[j] for each index j you visited in the array.

Return the maximum score you can get.

Example 1:

Input: nums = [1,-1,-2,4,-7,3], k = 2
Output: 7
Explanation: You can choose your jumps forming the subsequence [1,-1,4,3] (underlined above). The sum is 7.

Example 2:

Input: nums = [10,-5,-2,4,0,3], k = 3
Output: 17
Explanation: You can choose your jumps forming the subsequence [10,4,3] (underlined above). The sum is 17.

Example 3:

Input: nums = [1,-5,-20,4,-1,3,-6,-3], k = 2
Output: 0

问题理解

给定一个 0 索引 的整数数组 nums 和一个整数 k。你最初站在索引 0 处。在每一次移动中,你可以向前跳跃最多 k 步,但不能跳出数组的边界。也就是说,你可以从索引 i 跳到范围 [i + 1, min(n - 1, i + k)] 内的任意索引。

你的目标是到达数组的最后一个索引(索引 n - 1)。你的 得分 是你访问过的所有索引 j 对应的 nums[j] 的总和。

要求返回 你能获得的最大得分

解决思路

这是一个典型的动态规划问题。我们需要找到从索引 0 到索引 n - 1 的最大得分路径。

  • 状态定义:

    • dp[i] 表示从索引 0 跳到索引 i 的最大得分。
  • 状态转移:

    • 对于每个索引 i,我们需要检查从 [ i − k , i − 1 ] [i - k, i - 1] [ik,i1] 范围内的所有可能的前一个位置 j,并选择使得 dp[j] + nums[i] 最大的值。
  • 状态转移方程为:
    d p [ i ] = m a x ( d p [ j ] + n u m s [ i ] ) 其中 j ∈ [ i − k , i − 1 ] dp[i]=max(dp[j]+nums[i])其中j∈[i−k,i−1] dp[i]=max(dp[j]+nums[i])其中j[ik,i1]

  • 初始条件:dp[0] = nums[0],因为起点是索引 0。

  • 优化:

    • 直接使用动态规划会导致时间复杂度为 O ( n × k ) O(n×k) O(n×k),对于较大的 n n n k k k 可能无法通过。
    • 可以使用单调队列(Monotonic Queue)优化,将时间复杂度降低到 O ( n ) O(n) O(n)
#include <iostream>
#include <vector>
#include <deque>
#include <algorithm>
using namespace std;

int maxResult(vector<int>& nums, int k) {
    int n = nums.size();
    vector<int> dp(n); // dp[i] 表示跳到索引 i 的最大得分
    dp[0] = nums[0];   // 初始条件
    deque<int> dq;     // 单调队列,存储索引
    dq.push_back(0);   // 初始队列

    for (int i = 1; i < n; i++) {
        // 移除不在窗口范围内的索引
        while (!dq.empty() && dq.front() < i - k) {
            dq.pop_front();
        }
        
        // 更新 dp[i]
        dp[i] = dp[dq.front()] + nums[i];
        
        // 维护单调队列
        while (!dq.empty() && dp[i] >= dp[dq.back()]) {
            dq.pop_back();
        }
        dq.push_back(i);
    }
    
    return dp[n - 1]; // 返回最后一个索引的最大得分
}

代码说明

  • 动态规划数组 dp
    • dp[i] 表示从索引 0 跳到索引 i 的最大得分。
    • 初始条件:dp[0] = nums[0]
  • 单调队列 dq
    • 用于维护当前窗口 [ i − k , i − 1 ] [i - k, i - 1] [ik,i1] 内的最大值对应的索引。
    • 队列中的索引对应的 dp 值是递减的。
  • 遍历数组:
    • 对于每个索引 i,移除队列中不在窗口范围内的索引。
    • 更新 dp[i]dp[dq.front()] + nums[i]
    • 维护单调队列,确保队列中的索引对应的 dp 值是递减的。
  • 返回结果:
    • 最终返回 dp[n - 1],即最后一个索引的最大得分。

复杂度分析

  • 时间复杂度:每个索引最多入队和出队一次,因此时间复杂度为 O ( n ) O(n) O(n)
  • 空间复杂度:需要额外的 dp 数组和单调队列,空间复杂度为 O ( n ) O(n) O(n)

总结

  • 使用动态规划结合单调队列优化,可以高效地解决这个问题。
  • 时间复杂度为 O ( n ) O(n) O(n),适用于较大的输入规模。

相关文章:

  • 场景题:10亿QQ用户,如何统计在线人数?
  • 2025最新在GitHub上搭建个人图床,保姆级图文教程,实现图片高效管理
  • 通过RK3588的cc-linaro-7.5.0交叉编译器搭建QT交叉编译环境QtCreator(无需编译QT源码)
  • 将数据库结构化数据整合到RAG问答中的方式
  • android .rc文件
  • 【图像识别UI自动测试技术第二章】模版匹配算法学习分享
  • office或者word排版中,复制/黏贴进来文字不会自动换行,如何处理?
  • 系统架构设计师—计算机基础篇—进度管理
  • 在线研讨会 | 加速游戏和AI应用,全面认识Imagination DXTP GPU
  • 防火墙虚拟系统实验
  • leetcode 1328. 破坏回文串 中等
  • FieldFox 手持射频与微波分析仪
  • 力扣刷题DAY5(二分/简单+滑动窗口/中等)
  • Composition API
  • 在 C++ 中,通常会使用 `#define` 来定义宏,并通过这种方式发出警告或提示。
  • 线程、进程
  • 大模型生成长度预测器
  • Solon AI —— RAG
  • 推流项目的ffmpeg配置和流程重点总结一下
  • 【Elasticsearch】Elasticsearch 中使用 HDFS 存储快照
  • 网站如何不被收录/平台运营
  • 网站权重转移做排名/绍兴网站快速排名优化
  • 外贸网站建设价格/百度荤seo公司
  • 开发网站怎么挣钱/b2b电子商务网站
  • 六安市网站制作/百度联盟官网
  • 用jsp做的动态网站/广州seo怎么做