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

📅  最后修改于: 2021-04-24 15:23:56             🧑  作者: Mango

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

例子:

方法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


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


输出:
30

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

方法二:
第二种方法还要求使用动态编程。这种方法基于Bellman ford的DP解决方案,以实现单源最短路径。在Bellman的福特SSSP中,主要思想是通过使边缘最小化来找到下一个顶点,我们可以通过对数组中两个元素的绝对值进行最小化来找到下一个索引。

为了解决任何DP问题,我们首先猜测该子问题的所有可能解决方案,并记住它们,然后选择该子问题的最佳解决方案。我们为问题写了“重复发生”

重复发生: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

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
输出:
69

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