Given an array of integers arr and an integer d. In one step you can jump from index i to index:

i + x where: i + x < arr.length and 0 < x <= d.
i - x where: i - x >= 0 and 0 < x <= d.
In addition, you can only jump from index i to index j if arr[i] > arr[j] and arr[i] > arr[k] for all indices k between i and j (More formally min(i, j) < k < max(i, j)).

You can choose any index of the array and start jumping. Return the maximum number of indices you can visit.

Notice that you can not jump outside of the array at any time.

题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/jump-game-v
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

-----------------------------------------------------------------------------------------------------------------

【难点分析】

某位置可访问的最多节点数与周围i-x ~ i+x的节点有关,容易想到用动态规划的方法来做。然而一个节点能到达的节点数不仅与左半边节点相关,也与右半边节点相关,所以不能简单的从0开始遍历整个数组。

【解决方案】:

方案一:

对可以访问的节点数从1开始进行遍历,即dp[i][j] 表示第i个节点是否可以访问j个节点,直到左右dp[i][j]都为false时循环结束。对每一个dp[i][j],寻找他的左边及右边满足条件的节点中可以使他为true的节点,一旦发现后便退出循环。

class Solution {
public:
int maxJumps(vector<int>& arr, int d) {
int n = arr.size();
vector<vector<bool>> dp(n, vector<bool>(n+, false));
for(int i = ; i < n; ++i)
dp[i][] = true;
for(int jp = ; jp <= n; jp++) {
bool flag = false;
for(int i = ; i < n; ++i) {
if(!dp[i][jp-]) continue;
for(int j = i-; j >= && i-j <= d && arr[j] < arr[i]; j--) {
if(dp[j][jp-]) {
dp[i][jp] = true;
//cout << i << ", " << jp << endl;
flag = true;
break;
}
}
if(dp[i][jp]) continue;
for(int j = i+; j < n && j-i <= d && arr[j] < arr[i]; j++) {
if(dp[j][jp-]) {
dp[i][jp] = true;
//cout << i << ", " << jp << endl;
flag = true;
break;
}
}
}
if(!flag) return jp;
}
return n+;
}
};

时间复杂度:O(d*n^2)

方案二.

对于需要根据未知状态来确定当前状态值的动态规划问题,可以用记忆化搜索方法来解决,即如果dp[i] = func(dp[j]), 若dp[j]还未求出,则先去求dp[j]。这种方法要注意的是是否存在循环的状况,即类似于dp[i] = func(dp[j]), dp[j] = func(dp[k]), dp[k] = func(dp[i])。

因为本题中如果dp[i]需要由dp[j]来求得,则arr[j]必小于arr[i],dp[j]不可能由dp[i]直接或间接决定。

class Solution {
private:
vector<int> jmp;
public:
void dfs(vector<int>& arr, int id, int d) {
if(jmp[id] != ) return;
jmp[id] = ;
for(int t = ; t <= d && id+t < arr.size() && arr[id+t] < arr[id]; t++) {
dfs(arr, id+t, d);
jmp[id] = max(jmp[id], jmp[id+t]+);
}
for(int t = ; t <= d && id-t >= && arr[id-t] < arr[id]; t++) { dfs(arr, id-t, d);
jmp[id] = max(jmp[id], jmp[id-t]+);
} }
int maxJumps(vector<int>& arr, int d) {
int n = arr.size();
jmp.resize(n, );
for(int i = ; i < n; ++i) {
dfs(arr, i, d);
}
return *max_element(jmp.begin(), jmp.end());
}
};

时间复杂度: O(n*d) //每一个节点只需计算一次,需要与i-d ~ i+d的节点进行对比

Leetcode相似题目还有:135

【Leetcode】1340. Jump Game V 【动态规划/记忆性搜索】的更多相关文章

  1. sicily 1176. Two Ends (Top-down 动态规划+记忆化搜索 v.s. Bottom-up 动态规划)

    Description In the two-player game "Two Ends", an even number of cards is laid out in a ro ...

  2. Codevs_1017_乘积最大_(划分型动态规划/记忆化搜索)

    描述 http://codevs.cn/problem/1017/ 给出一个n位数,在数字中间添加k个乘号,使得最终的乘积最大. 1017 乘积最大 2000年NOIP全国联赛普及组NOIP全国联赛提 ...

  3. [NOIP2017] 逛公园 (最短路,动态规划&记忆化搜索)

    题目链接 Solution 我只会60分暴力... 正解是 DP. 状态定义: \(f[i][j]\) 代表 \(1\) 到 \(i\) 比最短路长 \(j\) 的方案数. 那么很显然最后答案也就是 ...

  4. Poj-P1088题解【动态规划/记忆化搜索】

    本文为原创,转载请注明:http://www.cnblogs.com/kylewilson/ 题目出处: http://poj.org/problem?id=1088 题目描述: 区域由一个二维数组给 ...

  5. UVA_437_The_Tower_of_the_Babylon_(DAG上动态规划/记忆化搜索)

    描述 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...

  6. 滑雪---poj1088(动态规划+记忆化搜索)

    题目链接:http://poj.org/problem?id=1088 有两种方法 一是按数值大小进行排序,然后按从小到大进行dp即可: #include <iostream> #incl ...

  7. 【LeetCode】Jump Game (一维动态规划 + 线性扫描)

    Given an array of non-negative integers, you are initially positioned at the first index of the arra ...

  8. Bone Collector(01背包+记忆化搜索)

    Bone Collector Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Tota ...

  9. 【UVA11324】 The Largest Clique (Tarjan+topsort/记忆化搜索)

    UVA11324 The Largest Clique 题目描述 给你一张有向图 \(G\),求一个结点数最大的结点集,使得该结点集中的任意两个结点 \(u\) 和 \(v\) 满足:要么 \(u\) ...

随机推荐

  1. [函数] PHP取二进制文件头快速判断文件类型

    一般我们都是按照文件扩展名来判断文件类型,但其实不太靠谱,因为可以通过修改扩展名来伪装文件类型.其实我们可以通过读取文件信息来识别,比如 PHP扩展中提供了类似 exif_imagetype 这样的函 ...

  2. ajax---post跨域思路

    ajax跨域需要加的代码 header("Access-Control-Allow-Methods:GET,POST");

  3. vue项目中上拉加载和下拉刷新页面的实现

    功能:上拉加载,下拉刷新 使用方法: 自己创建一个.vue的文件(我自己是创建了一个PullToRefresh.vue的文件),将代码粘贴进去,具体的样式问题自己在该文件中调整. <templa ...

  4. 2016年全球IC设计大厂营收排名:高通稳居龙头

    TrendForce旗下拓墣产业研究所最新研究统计,2016年全球前十大无晶圆IC设计业者营收中,高通(QCT)仍然稳居龙头宝座.而前三大业者高通.新博通(Broadcom)与联发科合计营收占前十名营 ...

  5. Codeforce-Ozon Tech Challenge 2020-D. Kuroni and the Celebration(交互题+DFS)

    After getting AC after 13 Time Limit Exceeded verdicts on a geometry problem, Kuroni went to an Ital ...

  6. USACO Training Section 1.2 双重回文数 Dual Palindrom

    题目描述 如果一个数从左往右读和从右往左读都是一样,那么这个数就叫做"回文数".例如,12321就是一个回文数,而77778就不是.当然,回文数的首和尾都应是非零的,因此0220就 ...

  7. 4)drf序列化组件 Serializer(偏底层)、ModelSerializer(重点)、ListModelSerializer(辅助群改)

    知识点:Serializer(偏底层).ModelSerializer(重点).ListModelSerializer(辅助群改) 一.Serializer 偏底层 一般不用 理解原理 1.序列化准备 ...

  8. docker部署gitlab

    Docker部署gitlab 一.前提条件 (1)     存在docker (2)     服务器可以联网(外网) (3)     服务器内存至少4G(内存不够会出现502错误) 内存不足502错误 ...

  9. 《Docker从入门到跑路》之基本用法介绍

    Docker是一种轻量级的虚拟化技术,它具备传统虚拟机无法比拟的优势,它更简易的安装和使用方式.更快的速度.服务集成和开源流程自动化. Docker的安装 安装Docker的基本要素:1.Docker ...

  10. opencv基于PCA降维算法的人脸识别

    opencv基于PCA降维算法的人脸识别(att_faces) 一.数据提取与处理 # 导入所需模块 import matplotlib.pyplot as plt import numpy as n ...