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. 二维vector的使用

    和数组一样,数组有二维的数组,vector也有二维的vector.下面就介绍一下二维vector的使用方法. 一般声明初始化二维vector有三种方法 (1) vector< vector< ...

  2. swoole学习--登录模块

    使用swoole+thinkphp6.0+redis 结合开发的登录模块,做完之后有几点感悟: 1.不要相信任务数据,包括请求的外部接口,特别是超时者部分,尽可能的交给task完成. 2.原来可以在入 ...

  3. 网站防止sql注入

    防止sql注入代码:(1)修改php.ini magic_quotes_gpc=Off,打开开关,不常用: (2)获取到参数后,调用$username = addslashes($username); ...

  4. thinkphp--导入导出xls文件

    /** * 数组转xls格式的excel文件 * @param array $data 需要生成excel文件的数组 * @param string $filename 生成的excel文件名 * 示 ...

  5. Nmap详细用法

    探测主机存活 (1)-sP :进行ping扫描 (2) -sn: ping探测扫描主机, 不进行端口扫描 (3)-sA     发送ACK探测存活 端口扫描 (1) -sS :半开放扫描 (2) sT ...

  6. 【Inno Setup】查看是否安装了VC++ 2015 Redistributeable

    可能有必要先测一下注册表的这一项是否存在 if RegValueExists(HKLM, 'SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0\VC\Ru ...

  7. HMAC算法及其应用

    HMAC算法及其应用 MAC HMAC HMAC的应用 HMAC实现举例 MAC 在现代的网络中,身份认证是一个经常会用到的功能,在身份认证过程中,有很多种方式可以保证用户信息的安全,而MAC(mes ...

  8. Galera将死——MySQL Group Replication正式发布

    2016-12-14 来源:InsideMySQL 作者:姜承尧 MySQL Group Replication GA 很多同学表示昨天的从你的全世界路过画风不对,好在今天MySQL界终于有大事情发生 ...

  9. mycat入门部署安装

    mycat是一种比较简单的中间件产品,可以帮助mysql进行分库,同时统一在一个逻辑库. 硬件环境:系统:centos 7.6数据库版本:5.7.19mycat:1.6..6.1 github上下载m ...

  10. linux服务器(CentOS)一键安装express框架

    express框架需要nodejs环境支持,没有安装node.js环境的同学可以参照下面这篇博客 linux服务器安装配置Node.js 好了,言归正传.先使用xshell或者其它软件连接我们的服务器 ...