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++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Function to find the minimum cost // to reach the end of an array void minCost( int arr[], int n)
{ // Base Case: When N < 3
if (n < 3) {
cout << arr[0];
return ;
}
// Store the results in table
int * dp = new int [n];
// Initialize base cases
dp[0] = arr[0];
dp[1] = dp[0] + arr[1] + arr[2];
// Iterate over the range[2, N - 2]
// to construct the dp array
for ( int i = 2; i < n - 1; i++)
dp[i] = min(dp[i - 2] + arr[i],
dp[i - 1] + arr[i]
+ arr[i + 1]);
// Handle case for the last index, i.e. N - 1
dp[n - 1] = min(dp[n - 2],
dp[n - 3] + arr[n - 1]);
// Print the answer
cout << dp[n - 1];
} // Driver Code int main()
{ int arr[] = { 9, 4, 6, 8, 5 };
int N = sizeof (arr) / sizeof (arr[0]);
minCost(arr, N);
return 0;
} |
// Java Program to implement // the above approach import java.io.*;
import java.util.*;
class GFG
{ // Function to find the minimum cost
// to reach the end of an array
static void minCost( int arr[], int n)
{
// Base Case: When N < 3
if (n < 3 ) {
System.out.println(arr[ 0 ]);
return ;
}
// Store the results in table
int dp[] = new int [n];
// Initialize base cases
dp[ 0 ] = arr[ 0 ];
dp[ 1 ] = dp[ 0 ] + arr[ 1 ] + arr[ 2 ];
// Iterate over the range[2, N - 2]
// to construct the dp array
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 ]);
// Handle case for the last index, i.e. N - 1
dp[n - 1 ] = Math.min(dp[n - 2 ], dp[n - 3 ] + arr[n - 1 ]);
// Print the answer
System.out.println(dp[n - 1 ]);
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 9 , 4 , 6 , 8 , 5 };
int N = arr.length;
minCost(arr, N);
}
} // This code is contributed by Kingash. |
# Python 3 program for the above approach # Function to find the minimum cost # to reach the end of an array def minCost(arr, n):
# Base Case: When N < 3
if (n < 3 ):
print (arr[ 0 ])
return
# Store the results in table
dp = [ 0 ] * n
# Initialize base cases
dp[ 0 ] = arr[ 0 ]
dp[ 1 ] = dp[ 0 ] + arr[ 1 ] + arr[ 2 ]
# Iterate over the range[2, N - 2]
# to construct the dp array
for i in range ( 2 , n - 1 ):
dp[i] = min (dp[i - 2 ] + arr[i],
dp[i - 1 ] + arr[i]
+ arr[i + 1 ])
# Handle case for the last index, i.e. N - 1
dp[n - 1 ] = min (dp[n - 2 ],
dp[n - 3 ] + arr[n - 1 ])
# Print the answer
print (dp[n - 1 ])
# Driver Code if __name__ = = "__main__" :
arr = [ 9 , 4 , 6 , 8 , 5 ]
N = len (arr)
minCost(arr, N)
# This code is contributed by ukasp.
|
// C# Program to implement // the above approach using System;
public class GFG
{ // Function to find the minimum cost
// to reach the end of an array
static void minCost( int []arr, int n)
{
// Base Case: When N < 3
if (n < 3) {
Console.WriteLine(arr[0]);
return ;
}
// Store the results in table
int []dp = new int [n];
// Initialize base cases
dp[0] = arr[0];
dp[1] = dp[0] + arr[1] + arr[2];
// Iterate over the range[2, N - 2]
// to construct the dp array
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]);
// Handle case for the last index, i.e. N - 1
dp[n - 1] = Math.Min(dp[n - 2], dp[n - 3] + arr[n - 1]);
// Print the answer
Console.WriteLine(dp[n - 1]);
}
// Driver Code
public static void Main( string [] args)
{
int []arr = { 9, 4, 6, 8, 5 };
int N = arr.Length;
minCost(arr, N);
}
} // This code is contributed by AnkThon |
<script> // Javascript program for the above approach // Function to find the minimum cost
// to reach the end of an array
function minCost(arr, n)
{
// Base Case: When N < 3
if (n < 3) {
document.write(arr[0]);
return ;
}
// Store the results in table
let dp = [];
// Initialize base cases
dp[0] = arr[0];
dp[1] = dp[0] + arr[1] + arr[2];
// Iterate over the range[2, N - 2]
// to construct the dp array
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]);
// Handle case for the last index, i.e. N - 1
dp[n - 1] = Math.min(dp[n - 2], dp[n - 3] + arr[n - 1]);
// Print the answer
document.write(dp[n - 1]);
}
// Driver Code let arr = [ 9, 4, 6, 8, 5 ];
let N = arr.length;
minCost(arr, N);
</script> |
20
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.
#include <bits/stdc++.h> using namespace std;
// Function to find the minimum cost // to reach the end of an array void minCost( int arr[], int n)
{ // Base Case: When N < 3
if (n < 3) {
cout << arr[0];
return ;
}
// Initialize variables prevPrev and prev
int prevPrev = arr[0];
int prev = arr[0] + arr[1] + arr[2];
// Iterate over the range[2, N - 1]
// to construct the dp array
for ( int i = 2; i < n - 1; i++) {
int curr = min(prevPrev + arr[i], prev + arr[i] + arr[i + 1]);
prevPrev = prev;
prev = curr;
}
// Print the answer
cout << min(prevPrev, prev);
} // Driver Code int main()
{ int arr[] = { 9, 4, 6, 8, 5 };
int N = sizeof (arr) / sizeof (arr[0]);
minCost(arr, N);
return 0;
} |
import java.lang.*;
class Main {
public static void minCost( int [] arr, int n)
{
// Base Case: When N < 3
if (n < 3 ) {
System.out.println(arr[ 0 ]);
return ;
}
// Initialize variables prevPrev and prev
int prevPrev = arr[ 0 ];
int prev = arr[ 0 ] + arr[ 1 ] + arr[ 2 ];
// Iterate over the range[2, N - 1]
// to construct the dp array
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;
}
// Print the answer
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);
}
} |
def minCost(arr, n):
# Base Case: When N < 3
if n < 3 :
return arr[ 0 ]
# Initialize variables prevPrev and prev
prevPrev = arr[ 0 ]
prev = arr[ 0 ] + arr[ 1 ] + arr[ 2 ]
# Iterate over the range[2, N - 1]
# to construct the dp array
for i in range ( 2 , n - 1 ):
curr = min (prevPrev + arr[i], prev + arr[i] + arr[i + 1 ])
prevPrev = prev
prev = curr
# Print the answer
return min (prevPrev, prev)
arr = [ 9 , 4 , 6 , 8 , 5 ]
N = len (arr)
print (minCost(arr, N))
|
using System;
class Program
{ // Function to find the minimum cost to reach the end of an array
static void MinCost( int [] arr, int n)
{
// Base Case: When n < 3
if (n < 3)
{
Console.WriteLine(arr[0]);
return ;
}
// Initialize variables prevPrev and prev
int prevPrev = arr[0];
int prev = arr[0] + arr[1] + arr[2];
// Iterate over the range [2, n - 2] to construct the DP array
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;
}
// Print the answer, which is the minimum of prevPrev and prev
Console.WriteLine(Math.Min(prevPrev, prev));
}
// Driver Code
static void Main( string [] args)
{
int [] arr = { 9, 4, 6, 8, 5 };
int N = arr.Length;
MinCost(arr, N);
}
} |
// Function to find the minimum cost // to reach the end of an array function minCost(arr, n) {
// Base Case: When N < 3
if (n < 3) {
console.log(arr[0]);
return ;
}
// Initialize variables prevPrev and prev
let prevPrev = arr[0];
let prev = arr[0] + arr[1] + arr[2];
// Iterate over the range[2, N - 1]
// to construct the dp array
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;
}
// Print the answer
console.log(Math.min(prevPrev, prev));
} // Driver Code const arr = [9, 4, 6, 8, 5]; const N = arr.length; minCost(arr, N); |
15
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.