📌  相关文章
📜  允许最大跳转 K 索引时到达数组末尾的最小成本

📅  最后修改于: 2021-09-17 16:02:22             🧑  作者: Mango

给定一个由N 个整数组成的数组arr[]和一个整数K ,如果j ≤ i + k ,则可以从索引i移动到任何其他j 。从一个索引i移动到另一个索引j的成本是abs(arr[i] – arr[j]) 。最初,我们从索引0开始,我们需要到达最后一个索引,即N – 1 。任务是以尽可能小的成本到达最后一个索引。
例子:

方法一:问题可以用动态规划解决。我们从索引 0 开始,我们可以访问从 i+1 到 i+k 的任何索引,因此所有路径的最小成本将存储在 dp[i] 中。一旦我们达到 N-1,这将是我们的基本情况。使用记忆化来记忆状态,这样我们就不需要再次重新访问状态来降低复杂性。
下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
 
// Function to return the minimum cost
// to reach the last index
int FindMinimumCost(int ind, int a[],
                    int n, int k, int dp[])
{
 
    // If we reach the last index
    if (ind == (n - 1))
        return 0;
 
    // Already visited state
    else if (dp[ind] != -1)
        return dp[ind];
    else {
 
        // Initially maximum
        int ans = INT_MAX;
 
        // Visit all possible reachable index
        for (int i = 1; i <= k; i++) {
 
            // If inside range
            if (ind + i < n)
                ans = min(ans, abs(a[ind + i] - a[ind])
                          + FindMinimumCost(ind + i, a,
                                             n, k, dp));
 
            // We cannot move any further
            else
                break;
        }
 
        // Memoize
        return dp[ind] = ans;
    }
}
 
// Driver Code
int main()
{
    int a[] = { 10, 30, 40, 50, 20 };
    int k = 3;
    int n = sizeof(a) / sizeof(a[0]);
    int dp[n];
    memset(dp, -1, sizeof dp);
    cout << FindMinimumCost(0, a, n, k, dp);
 
    return 0;
}


Java
// Java implementation of the approach
import java.util.*;
 
class GfG
{
 
// Function to return the minimum cost
// to reach the last index
static int FindMinimumCost(int ind, int a[],
                        int n, int k, int dp[])
{
 
    // If we reach the last index
    if (ind == (n - 1))
        return 0;
 
    // Already visited state
    else if (dp[ind] != -1)
        return dp[ind];
    else {
 
        // Initially maximum
        int ans = Integer.MAX_VALUE;
 
        // Visit all possible reachable index
        for (int i = 1; i <= k; i++)
        {
 
            // If inside range
            if (ind + i < n)
                ans = Math.min(ans, Math.abs(a[ind + i] - a[ind]) +
                            FindMinimumCost(ind + i, a, n, k, dp));
 
            // We cannot move any further
            else
                break;
        }
 
        // Memoize
        return dp[ind] = ans;
    }
}
 
// Driver Code
public static void main(String[] args)
{
    int a[] = { 10, 30, 40, 50, 20 };
    int k = 3;
    int n = a.length;
    int dp[] = new int[n];
    Arrays.fill(dp, -1);
    System.out.println(FindMinimumCost(0, a, n, k, dp));
}
}
 
// This code is contributed by Prerna Saini


Python3
# Python 3 implementation of the approach
import sys
 
# Function to return the minimum cost
# to reach the last index
def FindMinimumCost(ind, a, n, k, dp):
     
    # If we reach the last index
    if (ind == (n - 1)):
        return 0
 
    # Already visited state
    elif (dp[ind] != -1):
        return dp[ind]
    else:
         
        # Initially maximum
        ans = sys.maxsize
 
        # Visit all possible reachable index
        for i in range(1, k + 1):
             
            # If inside range
            if (ind + i < n):
                ans = min(ans, abs(a[ind + i] - a[ind]) +
                      FindMinimumCost(ind + i, a, n, k, dp))
 
            # We cannot move any further
            else:
                break
 
        # Memoize
        dp[ind] = ans
        return ans
 
# Driver Code
if __name__ == '__main__':
    a = [10, 30, 40, 50, 20]
    k = 3
    n = len(a)
    dp = [-1 for i in range(n)]
    print(FindMinimumCost(0, a, n, k, dp))
 
# This code is contributed by
# Surendra_Gangwar


C#
// C# implementation of the above approach
using System;
 
class GfG
{
 
    // Function to return the minimum cost
    // to reach the last index
    static int FindMinimumCost(int ind, int []a,
                            int n, int k, int []dp)
    {
     
        // If we reach the last index
        if (ind == (n - 1))
            return 0;
     
        // Already visited state
        else if (dp[ind] != -1)
            return dp[ind];
             
        else {
     
            // Initially maximum
            int ans = int.MaxValue;
     
            // Visit all possible reachable index
            for (int i = 1; i <= k; i++)
            {
     
                // If inside range
                if (ind + i < n)
                    ans = Math.Min(ans, Math.Abs(a[ind + i] - a[ind]) +
                                FindMinimumCost(ind + i, a, n, k, dp));
     
                // We cannot move any further
                else
                    break;
            }
     
            // Memoize
            return dp[ind] = ans;
        }
    }
     
    // Driver Code
    public static void Main()
    {
        int []a = { 10, 30, 40, 50, 20 };
        int k = 3;
        int n = a.Length;
        int []dp = new int[n];
        for(int i = 0; i < n ; i++)
            dp[i] = -1 ;
     
        Console.WriteLine(FindMinimumCost(0, a, n, k, dp));
    }
}
 
// This code is contributed by Ryuga


PHP


Javascript


C++
// C++ implementation of the approach
#include 
 
using namespace std;
 
// Function for returning the min of two elements
int min(int a, int b) {
    return (a > b) ? b : a;
}
 
int minCostJumpsDP(vector  & A, int k) {
    // for calculating the number of elements
    int size = A.size();
 
    // Allocating Memo table and
    // initializing with INT_MAX
    vector  x(size, INT_MAX); 
 
    // Base case
    x[0] = 0;
 
    // For every element relax every reachable
    // element ie relax next k elements
    for (int i = 0; i < size; i++) {
        // reaching next k element
        for (int j = i + 1; j < i + k + 1; j++) {
            // Relaxing the element
            x[j] = min(x[j], x[i] + abs(A[i] - A[j]));
        }
    }
 
    // return the last element in the array
    return x[size - 1];
}
 
 
// Driver Code
int main()
{
    vector  input { 83, 26, 37, 35, 33, 35, 56 };
    cout << minCostJumpsDP(input, 3);
    return 0;
}


Java
// Java implementation of the approach
import java.util.*;
class GFG
{
 
// Function for returning the
// min of two elements
static int min(int a, int b)
{
    return (a > b) ? b : a;
}
 
static int minCostJumpsDP(int []A, int k)
{
    // for calculating the number of elements
    int size = A.length;
 
    // Allocating Memo table and
    // initializing with INT_MAX
    int []x = new int[size];
    Arrays.fill(x, Integer.MAX_VALUE);
 
    // Base case
    x[0] = 0;
 
    // For every element relax every reachable
    // element ie relax next k elements
    for (int i = 0; i < size; i++)
    {
        // reaching next k element
        for (int j = i + 1;
                 j < i + k + 1 &&
                 j < size; j++)
        {
            // Relaxing the element
            x[j] = min(x[j], x[i] +
              Math.abs(A[i] - A[j]));
        }
    }
 
    // return the last element in the array
    return x[size - 1];
}
 
// Driver Code
public static void main(String []args)
{
    int []input = { 83, 26, 37, 35, 33, 35, 56 };
    System.out.println(minCostJumpsDP(input, 3));
}
}
 
// This code is contributed by Rajput-Ji


Python3
# Python3 implementation of the approach
import sys
 
def minCostJumpsDP(A, k):
     
    # for calculating the number of elements
    size = len(A)
 
    # Allocating Memo table and
    # initializing with INT_MAX
    x = [sys.maxsize] * (size)
 
    # Base case
    x[0] = 0
 
    # For every element relax every reachable
    # element ie relax next k elements
    for i in range(size):
         
        # reaching next k element
        j = i+1
        while j < i + k + 1 and j < size:
             
            # Relaxing the element
            x[j] = min(x[j], x[i] + abs(A[i] - A[j]))
            j += 1
         
    # return the last element in the array
    return x[size - 1]
 
# Driver Code
if __name__ == "__main__":
 
    input_ = [83, 26, 37, 35, 33, 35, 56]
    print(minCostJumpsDP(input_, 3))
     
# This code is contributed by Rituraj Jain


C#
// C# implementation of the approach
using System;
 
class GFG
{
 
// Function for returning the
// min of two elements
static int min(int a, int b)
{
    return (a > b) ? b : a;
}
 
static int minCostJumpsDP(int []A, int k)
{
    // for calculating the number of elements
    int size = A.Length;
 
    // Allocating Memo table and
    // initializing with INT_MAX
    int []x = new int[size];
    for (int i = 0; i < size; i++)
        x[i] = int.MaxValue;
    // Base case
    x[0] = 0;
 
    // For every element relax every reachable
    // element ie relax next k elements
    for (int i = 0; i < size; i++)
    {
        // reaching next k element
        for (int j = i + 1;
                 j < i + k + 1 &&
                 j < size; j++)
        {
            // Relaxing the element
            x[j] = min(x[j], x[i] +
            Math.Abs(A[i] - A[j]));
        }
    }
 
    // return the last element in the array
    return x[size - 1];
}
 
// Driver Code
public static void Main(String []args)
{
    int []input = { 83, 26, 37, 35, 33, 35, 56 };
    Console.WriteLine(minCostJumpsDP(input, 3));
}
}
 
// This code is contributed by 29AjayKumar


Javascript


输出:

30

时间复杂度: O(N * K)
辅助空间: O(N)
方法二:
第二种方法也需要使用动态规划。该方法基于 Bellman Ford 的单源最短路径 DP 解决方案。在 Bellman 的 Ford SSSP 中,主要思想是通过在边上最小化来找到下一个顶点,我们可以像在数组的两个元素的 abs 值上最小化一样来找到下一个索引。
为了解决任何 DP 问题,我们首先猜测子问题的所有可能解决方案并记住它们,然后选择子问题的最佳解决方案。我们为这个问题写了 Recurrence
循环:DP(j) = min{DP(i) + abs(A[i] – A[j])} 其中 i 在 [0, N-1] 中,j 在 [i + 1, j + k 中+ 1],k 是允许的跳转次数。这也可以与 SSSP 中的松弛进行比较。我们将放宽每个下一个平易近人的索引。

下面是自底向上方法的实现:

C++

// C++ implementation of the approach
#include 
 
using namespace std;
 
// Function for returning the min of two elements
int min(int a, int b) {
    return (a > b) ? b : a;
}
 
int minCostJumpsDP(vector  & A, int k) {
    // for calculating the number of elements
    int size = A.size();
 
    // Allocating Memo table and
    // initializing with INT_MAX
    vector  x(size, INT_MAX); 
 
    // Base case
    x[0] = 0;
 
    // For every element relax every reachable
    // element ie relax next k elements
    for (int i = 0; i < size; i++) {
        // reaching next k element
        for (int j = i + 1; j < i + k + 1; j++) {
            // Relaxing the element
            x[j] = min(x[j], x[i] + abs(A[i] - A[j]));
        }
    }
 
    // return the last element in the array
    return x[size - 1];
}
 
 
// Driver Code
int main()
{
    vector  input { 83, 26, 37, 35, 33, 35, 56 };
    cout << minCostJumpsDP(input, 3);
    return 0;
}

Java

// Java implementation of the approach
import java.util.*;
class GFG
{
 
// Function for returning the
// min of two elements
static int min(int a, int b)
{
    return (a > b) ? b : a;
}
 
static int minCostJumpsDP(int []A, int k)
{
    // for calculating the number of elements
    int size = A.length;
 
    // Allocating Memo table and
    // initializing with INT_MAX
    int []x = new int[size];
    Arrays.fill(x, Integer.MAX_VALUE);
 
    // Base case
    x[0] = 0;
 
    // For every element relax every reachable
    // element ie relax next k elements
    for (int i = 0; i < size; i++)
    {
        // reaching next k element
        for (int j = i + 1;
                 j < i + k + 1 &&
                 j < size; j++)
        {
            // Relaxing the element
            x[j] = min(x[j], x[i] +
              Math.abs(A[i] - A[j]));
        }
    }
 
    // return the last element in the array
    return x[size - 1];
}
 
// Driver Code
public static void main(String []args)
{
    int []input = { 83, 26, 37, 35, 33, 35, 56 };
    System.out.println(minCostJumpsDP(input, 3));
}
}
 
// This code is contributed by Rajput-Ji

蟒蛇3

# Python3 implementation of the approach
import sys
 
def minCostJumpsDP(A, k):
     
    # for calculating the number of elements
    size = len(A)
 
    # Allocating Memo table and
    # initializing with INT_MAX
    x = [sys.maxsize] * (size)
 
    # Base case
    x[0] = 0
 
    # For every element relax every reachable
    # element ie relax next k elements
    for i in range(size):
         
        # reaching next k element
        j = i+1
        while j < i + k + 1 and j < size:
             
            # Relaxing the element
            x[j] = min(x[j], x[i] + abs(A[i] - A[j]))
            j += 1
         
    # return the last element in the array
    return x[size - 1]
 
# Driver Code
if __name__ == "__main__":
 
    input_ = [83, 26, 37, 35, 33, 35, 56]
    print(minCostJumpsDP(input_, 3))
     
# This code is contributed by Rituraj Jain

C#

// C# implementation of the approach
using System;
 
class GFG
{
 
// Function for returning the
// min of two elements
static int min(int a, int b)
{
    return (a > b) ? b : a;
}
 
static int minCostJumpsDP(int []A, int k)
{
    // for calculating the number of elements
    int size = A.Length;
 
    // Allocating Memo table and
    // initializing with INT_MAX
    int []x = new int[size];
    for (int i = 0; i < size; i++)
        x[i] = int.MaxValue;
    // Base case
    x[0] = 0;
 
    // For every element relax every reachable
    // element ie relax next k elements
    for (int i = 0; i < size; i++)
    {
        // reaching next k element
        for (int j = i + 1;
                 j < i + k + 1 &&
                 j < size; j++)
        {
            // Relaxing the element
            x[j] = min(x[j], x[i] +
            Math.Abs(A[i] - A[j]));
        }
    }
 
    // return the last element in the array
    return x[size - 1];
}
 
// Driver Code
public static void Main(String []args)
{
    int []input = { 83, 26, 37, 35, 33, 35, 56 };
    Console.WriteLine(minCostJumpsDP(input, 3));
}
}
 
// This code is contributed by 29AjayKumar

Javascript


输出:
69

时间复杂度: O(N * K)
辅助空间: O(N)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程