[LeetCode] 656. Coin Path 硬币路径

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 青蛙跳

原文地址:https://www.cnblogs.com/lightwindy/p/9691924.html

时间: 2024-11-06 14:39:19

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

[LeetCode] Coin Path 硬币路径

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+1, i+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 integer B denotes 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+1, i+2,

[LeetCode] 71. Simplify Path 简化路径

Given an absolute path for a file (Unix-style), simplify it. For example,path = "/home/", => "/home"path = "/a/./b/../../c/", => "/c" Corner Cases: Did you consider the case where path = "/../"?In th

LeetCode --- 64. Minimum Path Sum

题目链接:Minimum Path Sum Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path. Note: You can only move either down or right at any point in time. 这道题的要求是在m*n

【LeetCode】Simplify Path

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

Leetcode:Triangle 三角形塔最小路径和

Triangle: Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below. For example, given the following triangle [ [2], [3,4], [6,5,7], [4,1,8,3] ] The minimum path sum from top to botto

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

一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum. For example: Given the below binary tree and sum = 22,

【Leetcode】Minimum Path Sum

Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path. Note: You can only move either down or right at any point in time. 思路:简单的动态规划题目,设f(m, n)为从(0, 0)到达(m

node.js(四)path优化(路径优化)

1.normalize函数的基本用法 normalize函数将不符合规范的路径经过格式化转换为标准路径,解析路径中的.与..外,还能去掉多余的斜杠. 如下示例: var path = require('path'); var data = path.normalize('/path///normalize/hi/..'); console.log(data); 运行结果: '/path/normalize/' 2.join函数的基本用法 join函数将传入的多个路径拼接为标准路径并将其格式化,返