给定一个由N个整数和整数K组成的数组arr [] ,如果j≤i + k ,则可以从索引i移动到其他j 。从一个索引i移至另一索引j的成本为abs(arr [i] – arr [j]) 。最初,我们从索引0开始,我们需要到达最后一个索引,即N – 1 。任务是以最小的成本达到最后的索引。
例子:
Input: arr[] = {10, 30, 40, 50, 20}, k = 3
Output: 30
0 -> 1 -> 4
the total cost will be: |10-30| + |30-20| = 30
Input: arr[] = {40, 10, 20, 70, 80, 10}, k = 4
Output: 30
方法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中的放松相提并论。我们将放宽每一个下一个可接近的指数。
// base case
memo[0] = 0;
for (i = 0 to N-1)
for (j = i+1 to i+k+1)
memo[j] = min(memo[j], memo[i] + abs(A[i] – A[j]));
以下是“自下而上”方法的实现:
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)