Minimum cost to reach the end of the array with maximum jumps of length K
Last Updated :
16 Dec, 2022
Given an array arr[] of size N and an integer K, one can move from an index i to any other index j such that j ? i+k. The cost of being at any index ‘i‘, is arr[i]. The task is to find the minimum cost to reach the end of the array starting from index 0.
Examples:
Input : arr[] = {2, 4, 1, 6, 3}, K = 2
Output: 6
Explanation: Path can be taken as 2 -> 1-> 3 = 6
Input: arr[] = {1, 2, 3, 4, 5, 6}, K = 3
Output: 10
Explanation: Path can be taken as 1->3->6 = 10
Naive Approach: The task can be solved using dynamic programming. Maintain a dp[] array where, where dp[i] indicates the minimum cost required to reach the ith index. Follow the below steps to solve the problem:
- Traverse all the K elements backward from the current element, & find the minimum dp value and add it to the current answer.
- So, calculating answer for ith index will be dp[i] = arr[i] + min(dp[j] for all j such that i-k <= j < i) .
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int solve(vector< int >& arr, int K)
{
int size = arr.size();
vector< int > dp(size, 0);
dp[0] = arr[0];
for ( int idx = 1; idx < size; idx++) {
int end = max(-1, idx - K - 1);
int mini = INT_MAX;
for ( int ptr = idx - 1; ptr > end; ptr--) {
mini = min(mini, dp[ptr]);
}
dp[idx] = arr[idx] + mini;
}
return dp[size - 1];
}
int main()
{
vector< int > arr = { 2, 4, 1, 6, 3 };
int K = 2;
int ans = solve(arr, K);
cout << ans << "\n" ;
}
|
Java
import java.io.*;
public class GFG {
static int solve( int [] arr, int K) {
int size = arr.length;
int [] dp = new int [size];
for ( int i = 0 ; i < size; i++) {
dp[i] = 0 ;
}
dp[ 0 ] = arr[ 0 ];
for ( int idx = 1 ; idx < size; idx++) {
int end = Math.max(- 1 , idx - K - 1 );
int mini = Integer.MAX_VALUE;
for ( int ptr = idx - 1 ; ptr > end; ptr--) {
mini = Math.min(mini, dp[ptr]);
}
dp[idx] = arr[idx] + mini;
}
return dp[size - 1 ];
}
public static void main(String args[]) {
int [] arr = { 2 , 4 , 1 , 6 , 3 };
int K = 2 ;
int ans = solve(arr, K);
System.out.println(ans);
}
}
|
Python3
def solve(arr, K):
size = len (arr)
dp = [ 0 ] * (size)
dp[ 0 ] = arr[ 0 ]
for idx in range ( 1 , size, 1 ):
end = max ( - 1 , idx - K - 1 )
mini = float ( 'inf' )
for ptr in range (idx - 1 , end, - 1 ):
mini = min (mini, dp[ptr])
dp[idx] = arr[idx] + mini
return (dp[ - 1 ])
if __name__ = = "__main__" :
arr = [ 2 , 4 , 1 , 6 , 3 ]
K = 2
ans = solve(arr, K)
print (ans)
|
C#
using System;
class GFG
{
static int solve( int []arr, int K)
{
int size = arr.Length;
int []dp = new int [size];
for ( int i = 0; i < size; i++) {
dp[i] = 0;
}
dp[0] = arr[0];
for ( int idx = 1; idx < size; idx++) {
int end = Math.Max(-1, idx - K - 1);
int mini = Int32.MaxValue;
for ( int ptr = idx - 1; ptr > end; ptr--) {
mini = Math.Min(mini, dp[ptr]);
}
dp[idx] = arr[idx] + mini;
}
return dp[size - 1];
}
public static void Main()
{
int []arr = { 2, 4, 1, 6, 3 };
int K = 2;
int ans = solve(arr, K);
Console.WriteLine(ans);
}
}
|
Javascript
<script>
function solve(arr, K) {
let size = arr.length
let dp = new Array(size + 1).fill(0)
dp[0] = arr[0]
for (let idx = 1; idx < size; idx++) {
let end = Math.max(-1, idx - K - 1)
let mini = Number.MAX_VALUE
for (let ptr = idx - 1; ptr > end; ptr--)
mini = Math.min(mini, dp[ptr])
dp[idx] = arr[idx] + mini
}
return dp[size - 1]
}
let arr = [2, 4, 1, 6, 3]
let K = 2
ans = solve(arr, K)
document.write(ans)
</script>
|
Time Complexity: O(N * K)
Auxiliary Space: O(N)
Efficient Approach: Instead of calculating the minimum cost for each index, use the sliding window approach. Use the sliding window of size K, such that the minimum element is always present at the front and sorted order is maintained. Follow the below steps to solve the problem:
- Initialize deque to hold the data, as it supports the efficient operation of popping elements from both front and backside.
- Insert the first element along with its index in the deque. The index is also inserted to track if any element is within the window limit of size K.
- Then, start looping from index 1 till the end of the array. For each index, remove all the elements from the front which are out of the current window size, i.e difference between indices > k.
- Calculate current_value as the summation of arr[i] and the first value of dequeue. Here the first value is added, because it is the smallest value in the current window.
- Then pop all the elements from the back from deque which has a value greater than or equal to current_value. This is done to maintain a sorted order in the deque.
- Finally return the last value in the deque, showing the cost to reach the last index of the array.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int solve( int arr[], int K, int size)
{
deque<pair< int , int > > ququ;
ququ.push_back({ 0, arr[0] });
for ( int i = 1; i < size; i++) {
while ((ququ.size() > 0)
&& ((i - ququ.front().first) > K))
ququ.pop_front();
int curr_val = arr[i] + ququ.front().second;
while ((ququ.size() > 0)
&& (curr_val <= ququ.back().second))
ququ.pop_back();
ququ.push_back({ i, curr_val });
}
return ququ.back().second;
}
int main()
{
int arr[] = { 2, 4, 1, 6, 3 };
int K = 2;
int size = sizeof (arr) / sizeof (arr[0]);
int ans = solve(arr, K, size);
cout << ans << endl;
return 0;
}
|
Java
import java.util.*;
import java.io.*;
class GFG{
public static int solve( int arr[], int K, int size)
{
Deque<pair> ququ = new LinkedList<pair>();
ququ.addLast( new pair( 0 , arr[ 0 ]));
for ( int i = 1 ; i < size ; i++) {
while ((ququ.size() > 0 ) && ((i - ququ.getFirst().x) > K))
ququ.removeFirst();
int curr_val = arr[i] + ququ.getFirst().y;
while ((ququ.size() > 0 ) && (curr_val <= ququ.getLast().y))
ququ.removeLast();
ququ.addLast( new pair(i, curr_val));
}
return ququ.getLast().y;
}
public static void main(String args[])
{
int arr[] = { 2 , 4 , 1 , 6 , 3 };
int K = 2 ;
int size = arr.length;
int ans = solve(arr, K, size);
System.out.println(ans);
}
}
class pair{
Integer x;
Integer y;
pair( int a, int b){
this .x = a;
this .y = b;
}
}
|
Python3
from collections import deque
def solve(arr, K):
size = len (arr)
ququ = deque()
ququ.append(( 0 , arr[ 0 ]))
for i in range ( 1 , size, 1 ):
while (ququ and i - ququ[ 0 ][ 0 ] > K):
ququ.popleft()
curr_val = arr[i] + ququ[ 0 ][ 1 ]
while (ququ and curr_val < = ququ[ - 1 ][ 1 ]):
ququ.pop()
ququ.append((i, curr_val))
return ququ[ - 1 ][ 1 ]
if __name__ = = "__main__" :
arr = [ 2 , 4 , 1 , 6 , 3 ]
K = 2
ans = solve(arr, K)
print (ans)
|
C#
using System;
using System.Collections.Generic;
class GFG
{
class pair
{
public int x, y;
public pair( int a, int b)
{
this .x = a;
this .y = b;
}
}
public static int solve( int [] arr, int K, int size)
{
LinkedList<pair> ququ = new LinkedList<pair>();
ququ.AddLast( new pair(0, arr[0]));
for ( int i = 1; i < size; i++)
{
while ((ququ.Count > 0) && ((i - ququ.First.Value.x) > K))
ququ.RemoveFirst();
int curr_val = arr[i] + ququ.First.Value.y;
while ((ququ.Count > 0) && (curr_val <= ququ.Last.Value.y))
ququ.RemoveLast();
ququ.AddLast( new pair(i, curr_val));
}
return ququ.Last.Value.y;
}
public static void Main()
{
int [] arr = { 2, 4, 1, 6, 3 };
int K = 2;
int size = arr.Length;
int ans = solve(arr, K, size);
Console.Write(ans);
}
}
|
Javascript
function solve(arr, K, size)
{
ququ = [];
ququ.push({ "first" :0,
"second" : arr[0] });
for (let i = 1; i < size; i++) {
while ((ququ.length > 0)
&& ((i - ququ[0].first) > K))
ququ.shift();
let curr_val = arr[i] + ququ[0].second;
while ((ququ.length > 0)
&& (curr_val <= ququ[ququ.length-1].second))
ququ.pop();
ququ.push({ "first" : i,
"second" : curr_val });
}
return ququ[ququ.length-1].second;
}
let arr = [ 2, 4, 1, 6, 3 ];
let K = 2;
let size = arr.length;
let ans = solve(arr, K, size);
console.log(ans);
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...