Minimize cost to reach end of an array by two forward jumps or one backward jump in each move
Given an array arr[] consisting of N positive integers, the task is to find the minimum cost required to either cross the array or reach the end of the array by only moving to indices (i + 2) and (i – 1) from the ith index.
Examples:
Input: arr[] = {5, 1, 2, 10, 100}
Output: 18
Explanation:
Optimal cost path (0 based indexing): 0 ? 2 ? 1 ? 3 ? 5
Therefore, the minimum cost = 5 + 2 + 1 + 10 = 18.
Input: arr[] = {9, 4, 6, 8, 5}
Output: 20
Explanation:
Optimal cost path (0 based indexing): 0 ? 2 ? 4
Therefore, the minimum cost = 9 + 6 + 5 = 20
Naive Approach: The given problem can be solved based on the following observations:
- Since all costs are positive, it will never be an optimal option to move more than one step backward, hence to reach a particular index i of the array, either jump directly from the (i – 2)th index or jump from (i – 1)th to (i + 1)th index, i.e. (2 jumps forward), followed by 1 backward jump, i.e. from (i + 1)th index to ith index.
- Now, traverse from the end of the array recursively and for the elements at indices (i – 2) and (i – 1), calculate the minimum cost of the two. Therefore, the minimum cost to cross the array can be calculated using the following recurrence relation:
minCost(index) = minimum(minCost(index – 2) + arr[i], minCost(index – 1) + arr[i] + arr[i + 1])
Time Complexity: O(2N)
Auxiliary Space: O(1)
Efficient Approach: The approach discussed above has both Optimal Substructure and Overlapping Subproblems. Therefore it can be optimized by either using Memoization or Tabulation. Follow the steps below to solve the problem:
- Initialize an array dp[], where dp[i] stores the minimum cost to reach the ith index.
- Initialize dp[0] = arr[0] as the cost to reach the 0th index, which is equal to the value at the 0th index itself. Update dp[1] = arr[0] + arr[1] + arr[2], as to reach the 1st index, jump from the 0th index to 2nd index indexn to the 1st index.
- Iterate over the range [2, N – 2] using a variable i and update dp[i] as the minimum of (dp[i – 2] + arr[i]) and (dp[i – 1] + arr[i] + arr[i + 1]).
- For the last index (N – 1), update dp[N – 1] as minimum of (dp[N – 3] + arr[N – 1]) and (dp[N – 2]).
- After completing the above steps, print the value of dp[N – 1] as the result.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void minCost( int arr[], int n)
{
if (n < 3) {
cout << arr[0];
return ;
}
int * dp = new int [n];
dp[0] = arr[0];
dp[1] = dp[0] + arr[1] + arr[2];
for ( int i = 2; i < n - 1; i++)
dp[i] = min(dp[i - 2] + arr[i],
dp[i - 1] + arr[i]
+ arr[i + 1]);
dp[n - 1] = min(dp[n - 2],
dp[n - 3] + arr[n - 1]);
cout << dp[n - 1];
}
int main()
{
int arr[] = { 9, 4, 6, 8, 5 };
int N = sizeof (arr) / sizeof (arr[0]);
minCost(arr, N);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG
{
static void minCost( int arr[], int n)
{
if (n < 3 ) {
System.out.println(arr[ 0 ]);
return ;
}
int dp[] = new int [n];
dp[ 0 ] = arr[ 0 ];
dp[ 1 ] = dp[ 0 ] + arr[ 1 ] + arr[ 2 ];
for ( int i = 2 ; i < n - 1 ; i++)
dp[i] = Math.min(dp[i - 2 ] + arr[i],
dp[i - 1 ] + arr[i] + arr[i + 1 ]);
dp[n - 1 ] = Math.min(dp[n - 2 ], dp[n - 3 ] + arr[n - 1 ]);
System.out.println(dp[n - 1 ]);
}
public static void main(String[] args)
{
int arr[] = { 9 , 4 , 6 , 8 , 5 };
int N = arr.length;
minCost(arr, N);
}
}
|
Python3
def minCost(arr, n):
if (n < 3 ):
print (arr[ 0 ])
return
dp = [ 0 ] * n
dp[ 0 ] = arr[ 0 ]
dp[ 1 ] = dp[ 0 ] + arr[ 1 ] + arr[ 2 ]
for i in range ( 2 , n - 1 ):
dp[i] = min (dp[i - 2 ] + arr[i],
dp[i - 1 ] + arr[i]
+ arr[i + 1 ])
dp[n - 1 ] = min (dp[n - 2 ],
dp[n - 3 ] + arr[n - 1 ])
print (dp[n - 1 ])
if __name__ = = "__main__" :
arr = [ 9 , 4 , 6 , 8 , 5 ]
N = len (arr)
minCost(arr, N)
|
C#
using System;
public class GFG
{
static void minCost( int []arr, int n)
{
if (n < 3) {
Console.WriteLine(arr[0]);
return ;
}
int []dp = new int [n];
dp[0] = arr[0];
dp[1] = dp[0] + arr[1] + arr[2];
for ( int i = 2; i < n - 1; i++)
dp[i] = Math.Min(dp[i - 2] + arr[i],
dp[i - 1] + arr[i] + arr[i + 1]);
dp[n - 1] = Math.Min(dp[n - 2], dp[n - 3] + arr[n - 1]);
Console.WriteLine(dp[n - 1]);
}
public static void Main( string [] args)
{
int []arr = { 9, 4, 6, 8, 5 };
int N = arr.Length;
minCost(arr, N);
}
}
|
Javascript
<script>
function minCost(arr, n)
{
if (n < 3) {
document.write(arr[0]);
return ;
}
let dp = [];
dp[0] = arr[0];
dp[1] = dp[0] + arr[1] + arr[2];
for (let i = 2; i < n - 1; i++)
dp[i] = Math.min(dp[i - 2] + arr[i],
dp[i - 1] + arr[i] + arr[i + 1]);
dp[n - 1] = Math.min(dp[n - 2], dp[n - 3] + arr[n - 1]);
document.write(dp[n - 1]);
}
let arr = [ 9, 4, 6, 8, 5 ];
let N = arr.length;
minCost(arr, N);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Algorithm:
- Initialize two variables prevPrev and prev as arr[0] and arr[0]+arr[1]+arr[2] respectively.
- Iterate over the range [2, N-1] and for each index i:
a. Calculate the minimum cost to reach this index by comparing dp[i-1]+arr[i]+arr[i+1] and dp[i-2]+arr[i].
b. Update prevPrev as prev and prev as dp[i] for the next iteration.
- The minimum cost to reach the end of the array is the minimum of prevPrev and prev.
C++
#include <bits/stdc++.h>
using namespace std;
void minCost( int arr[], int n)
{
if (n < 3) {
cout << arr[0];
return ;
}
int prevPrev = arr[0];
int prev = arr[0] + arr[1] + arr[2];
for ( int i = 2; i < n - 1; i++) {
int curr = min(prevPrev + arr[i], prev + arr[i] + arr[i + 1]);
prevPrev = prev;
prev = curr;
}
cout << min(prevPrev, prev);
}
int main()
{
int arr[] = { 9, 4, 6, 8, 5 };
int N = sizeof (arr) / sizeof (arr[0]);
minCost(arr, N);
return 0;
}
|
Java
import java.lang.*;
class Main {
public static void minCost( int [] arr, int n)
{
if (n < 3 ) {
System.out.println(arr[ 0 ]);
return ;
}
int prevPrev = arr[ 0 ];
int prev = arr[ 0 ] + arr[ 1 ] + arr[ 2 ];
for ( int i = 2 ; i < n - 1 ; i++) {
int curr = Math.min(prevPrev + arr[i],
prev + arr[i] + arr[i + 1 ]);
prevPrev = prev;
prev = curr;
}
System.out.println(Math.min(prevPrev, prev));
}
public static void main(String[] args)
{
int [] arr = { 9 , 4 , 6 , 8 , 5 };
int N = arr.length;
minCost(arr, N);
}
}
|
Python3
def minCost(arr, n):
if n < 3 :
return arr[ 0 ]
prevPrev = arr[ 0 ]
prev = arr[ 0 ] + arr[ 1 ] + arr[ 2 ]
for i in range ( 2 , n - 1 ):
curr = min (prevPrev + arr[i], prev + arr[i] + arr[i + 1 ])
prevPrev = prev
prev = curr
return min (prevPrev, prev)
arr = [ 9 , 4 , 6 , 8 , 5 ]
N = len (arr)
print (minCost(arr, N))
|
C#
using System;
class Program
{
static void MinCost( int [] arr, int n)
{
if (n < 3)
{
Console.WriteLine(arr[0]);
return ;
}
int prevPrev = arr[0];
int prev = arr[0] + arr[1] + arr[2];
for ( int i = 2; i < n - 1; i++)
{
int curr = Math.Min(prevPrev + arr[i], prev + arr[i] + arr[i + 1]);
prevPrev = prev;
prev = curr;
}
Console.WriteLine(Math.Min(prevPrev, prev));
}
static void Main( string [] args)
{
int [] arr = { 9, 4, 6, 8, 5 };
int N = arr.Length;
MinCost(arr, N);
}
}
|
Javascript
function minCost(arr, n) {
if (n < 3) {
console.log(arr[0]);
return ;
}
let prevPrev = arr[0];
let prev = arr[0] + arr[1] + arr[2];
for (let i = 2; i < n - 1; i++) {
let curr = Math.min(prevPrev + arr[i], prev + arr[i] + arr[i + 1]);
prevPrev = prev;
prev = curr;
}
console.log(Math.min(prevPrev, prev));
}
const arr = [9, 4, 6, 8, 5];
const N = arr.length;
minCost(arr, N);
|
Complexity Analysis:
Time Complexity: O(N), where N is the size of the array. We are iterating over the array once to calculate the minimum cost to reach each index.
Space Complexity: O(1). We are not using any extra space for storing the intermediate results. We are just using two variables prevPrev and prev to store the results for the previous iterations.
Last Updated :
26 Oct, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...