Given an array A (index starts at 1) consisting of N integers: A1, A2, ..., AN and an integer B. The integer Bdenotes that from any place (suppose the index is i) in the array A, you can jump to any one of the place in the array A indexed i+1i+2, …, i+B if this place can be jumped to. Also, if you step on the index i, you have to pay Ai coins. If Ai is -1, it means you can’t jump to the place indexed i in the array.

Now, you start from the place indexed 1 in the array A, and your aim is to reach the place indexed N using the minimum coins. You need to return the path of indexes (starting from 1 to N) in the array you should take to get to the place indexed N using minimum coins.

If there are multiple paths with the same cost, return the lexicographically smallest such path.

If it's not possible to reach the place indexed N then you need to return an empty array.

Example 1:

Input: [1,2,4,-1,2], 2
Output: [1,3,5]

Example 2:

Input: [1,2,4,-1,2], 1
Output: []

Note:

  1. Path Pa1, Pa2, ..., Pan is lexicographically smaller than Pb1, Pb2, ..., Pbm, if and only if at the first i where Pai and Pbi differ, Pai < Pbi; when no such i exists, then n < m.
  2. A1 >= 0. A2, ..., AN (if exist) will in the range of [-1, 100].
  3. Length of A is in the range of [1, 1000].
  4. B is in the range of [1, 100].

给一个数组A,数组元素的值代表cost,一个整数B表示能走的最大步数。从第1个位置开始走,每次能走的步数是B步以内,走到某个位置就要付出该位置的cost,目标是到达最末尾位置,使得付出总cost值最小,输出所有路径。如果某个位置是-1,不可以走这个位置。如果有多个路径,输出按字母顺序排列。

解法:DP, 从后往前跳。首先判断最后一个位置是否为-1,如果是说明无法到达最后位置,返回空。用一个一维数组dp记录跳到i位置所用的最小cost, 从i位置跳时有B种跳法,再去判断每一个跳法的dp值。

dp[i] = A[i] + dp[j]  (dp[j]为从B种跳法中的一种的dp值)

Python:

# Time:  O(n * B)
# Space: O(n)
class Solution(object):
def cheapestJump(self, A, B):
"""
:type A: List[int]
:type B: int
:rtype: List[int]
"""
result = []
if not A or A[-1] == -1:
return result
n = len(A)
dp, next_pos = [float("inf")] * n, [-1] * n
dp[n-1] = A[n-1]
for i in reversed(xrange(n-1)):
if A[i] == -1:
continue
for j in xrange(i+1, min(i+B+1,n)):
if A[i] + dp[j] < dp[i]:
dp[i] = A[i] + dp[j]
next_pos[i] = j
if dp[0] == float("inf"):
return result
k = 0
while k != -1:
result.append(k+1)
k = next_pos[k]
return result  

C++:

class Solution {
public:
vector<int> cheapestJump(vector<int>& A, int B) {
if (A.back() == -1) return {};
int n = A.size();
vector<int> res, dp(n, INT_MAX), pos(n, -1);
dp[n - 1] = A[n - 1];
for (int i = n - 2; i >= 0; --i) {
if (A[i] == -1) continue;
for (int j = i + 1; j <= min(i + B, n - 1); ++j) {
if (dp[j] == INT_MAX) continue;
if (A[i] + dp[j] < dp[i]) {
dp[i] = A[i] + dp[j];
pos[i] = j;
}
}
}
if (dp[0] == INT_MAX) return res;
for (int cur = 0; cur != -1; cur = pos[cur]) {
res.push_back(cur + 1);
}
return res;
}
};

C++:

class Solution {
public:
vector<int> cheapestJump(vector<int>& A, int B) {
if (A.back() == -1) return {};
int n = A.size();
vector<int> res, dp(n, INT_MAX), pos(n, -1), len(n, 0);
dp[0] = 0;
for (int i = 0; i < n; ++i) {
if (A[i] == -1) continue;
for (int j = max(0, i - B); j < i; ++j) {
if (dp[j] == INT_MAX) continue;
int t = A[i] + dp[j];
if (t < dp[i] || (t == dp[i] && len[i] < len[j] + 1)) {
dp[i] = t;
pos[i] = j;
len[i] = len[j] + 1;
}
}
}
if (dp[n - 1] == INT_MAX) return res;
for (int cur = n - 1; cur != -1; cur = pos[cur]) {
res.insert(res.begin(), cur + 1);
}
return res;
}
};

C++:

class Solution {
public:
vector<int> cheapestJump(vector<int>& A, int B) {
vector<int> result;
if (A.empty() || A.back() == -1) {
return result;
}
const int n = A.size();
vector<int> dp(n, numeric_limits<int>::max()), next(n, -1);
dp[n - 1] = A[n - 1];
for (int i = n - 2; i >= 0; --i) {
if (A[i] == -1) {
continue;
}
for (int j = i + 1; j <= min(i + B, n - 1); ++j) {
if (dp[j] == numeric_limits<int>::max()) {
continue;
}
if (A[i] + dp[j] < dp[i]) {
dp[i] = A[i] + dp[j];
next[i] = j;
}
}
}
if (dp[0] == numeric_limits<int>::max()) {
return result;
}
int k = 0;
while (k != -1) {
result.emplace_back(k + 1);
k = next[k];
}
return result;
}
};

  

  

类似题目:

[LeetCode] 198. House Robber 打家劫舍

[LeetCode] 213. House Robber II 打家劫舍 II

[LeetCode] 55. Jump Game 跳跃游戏

[LeetCode] 45. Jump Game II 跳跃游戏 II

[LeetCode] 403. Frog Jump 青蛙跳

All LeetCode Questions List 题目汇总

[LeetCode] 656. Coin Path 硬币路径的更多相关文章

  1. [LeetCode] Coin Path 硬币路径

    Given an array A (index starts at 1) consisting of N integers: A1, A2, ..., AN and an integer B. The ...

  2. leetcode 656. Coin Path

    Given an array A (index starts at 1) consisting of N integers: A1, A2, ..., AN and an integer B. The ...

  3. [LeetCode] 322. Coin Change 硬币找零

    You are given coins of different denominations and a total amount of money amount. Write a function ...

  4. [LeetCode] 71. Simplify Path 简化路径

    Given an absolute path for a file (Unix-style), simplify it. For example,path = "/home/", ...

  5. LC 656. Coin Path 【lock, Hard】

    Given an array A (index starts at 1) consisting of N integers: A1, A2, ..., AN and an integer B. The ...

  6. [LeetCode] 518. Coin Change 2 硬币找零 2

    You are given coins of different denominations and a total amount of money. Write a function to comp ...

  7. 【一天一道LeetCode】#113. Path Sum II

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...

  8. [LeetCode] 62. Unique Paths 唯一路径

    A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The ...

  9. 【LeetCode】113. Path Sum II 解题报告(Python)

    [LeetCode]113. Path Sum II 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fu ...

随机推荐

  1. Mybatis容易遇到的问题

    1.MyBatis中#和$的区别? 1.使用#的原理是?占位符,而$的原理为直接字符串拼接方式 2.$方式一般使用在写数据库中的固定字段时候才会使用例如表名或者列名(select * from use ...

  2. 网络基础知识(http请求)

    http请求的过程 域名解析----TCP连接 ----发送请求-----响应请求----获取html代码----浏览器渲染 TCP是主机对主机层的控制传输协议,提供可靠的连接服务 TCP的三次握手 ...

  3. 12.基于vue-router的案例

    案例分析 用到的路由技术要点: 路由的基础用法 嵌套路由 路由重定向 路由传参 编程式导航 根据项目的整体布局划分好组件结构,通过路由导航控制组件的显示 1.抽离并渲染 App根组件 2.将左侧菜 单 ...

  4. hive 初始化数据库报错

    安装hive,初始化数据库的时候报错 schematool -dbType mysql -initSchema Metastore Connection Driver : com.mysql.cj.j ...

  5. JQuery系列(4) - AJAX方法

    jQuery对象上面还定义了Ajax方法($.ajax()),用来处理Ajax操作.调用该方法后,浏览器就会向服务器发出一个HTTP请求. $.ajax方法 $.ajax()的用法主要有两种. $.a ...

  6. ES6函数的个人总结

    默认参数: 1. 在 ES5 语法中,为函数形参指定默认值的写法: 写法一: function foo (bar) { bar = bar || 'abc'; console.log(bar) } f ...

  7. [Dynamic Programming] 198. House Robber

    You are a professional robber planning to rob houses along a street. Each house has a certain amount ...

  8. Tensorflow细节-P290-命名空间与tensorboard上的节点

    讲解几个重点知识 1.对于tf.get_variable()中的reuse,意思是,如果有名字一模一样的变量,则对这个变量继续使用,如果没有名字一模一样的变量,则创建这个变量 2.options=ru ...

  9. PostgreSQL 一些比较好用的字符串函数

    最近刚接触到PostgreSQL数据库,发现很多功能比较强大的内置函数,特此记录下来.示例下次再补. 1.concat 字符串连接函数 2.concat_ws concat_ws函数连接可自定义分隔符 ...

  10. RaiseFailFastException函数

    引发绕过所有异常处理程序(基于帧或矢量)的异常.引发此异常将终止应用程序并调用Windows错误报告(如果Windows错误报告正在运行). 原型: VOID WINAPI RaiseFailFast ...