给定一个由N 个整数组成的数组arr[]和一个整数K ,如果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
方法一:问题可以用动态规划解决。我们从索引 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 中的松弛进行比较。我们将放宽每个下一个平易近人的索引。
// 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
蟒蛇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 现场工作专业课程和学生竞争性编程现场课程。