Minimum cost incurred before the geek reaches stone n
Last Updated :
29 Oct, 2023
Given n stones and array heights[] and Geek is standing at stone 1 and can jump to one of the following: Stone i+1, i+2, … i+k stone and cost will be [hi – hj] is incurred, where j is the stone to land on. Find the minimum possible total cost incurred before the Geek reaches Stone n.
Examples:
Input: n = 5, k = 3, heights[] = {10, 30, 40, 50, 20}
Output: 30
Explanation: Geek will follow the path 1->2->5, and the total cost would be | 10 – 30 | + | 30 – 20 | = 30, which is minimum
Input: n = 3, k = 1, heights[] = {10, 20, 10}
Output: 20
Explanation: Geek will follow the path 1->2->3, and the total cost would be |10 – 20 | + |20 – 10| = 20.
Approach: This can be solved with the following idea:
Using Dynamic Programming, we can calculate the minimum cost to travel n stones. At each i, we will look for the minimum value within k steps.
Steps involved in the implementation of code:
- Initializing dp vector.
- Iterating for first k values for each index.
- check if stones before this particular index are giving less cost or not.
- If it is, update the dp for that particular index.
- if after traversing n > k is true.
- Again iterate for k + 1 to n, following the same procedure.
- Returning the dp[n – 1].
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
void minCost(vector< int >& heights, int n, int k)
{
vector< int > dp(n + 1);
dp[0] = 0;
dp[1] = abs (heights[0] - heights[1]);
for ( int i = 2; i <= min(n, k); i++) {
int x = INT_MAX;
for ( int j = 0; j < i; j++) {
if (( abs (heights[i] - heights[j]) + dp[j])
< x) {
x = abs (heights[i] - heights[j]) + dp[j];
}
}
dp[i] = x;
}
if (k < n) {
for ( int i = k + 1; i < n; i++) {
int x = INT_MAX;
for ( int j = (i - k); j < i; j++) {
if (( abs (heights[i] - heights[j]) + dp[j])
< x) {
x = abs (heights[i] - heights[j])
+ dp[j];
}
}
dp[i] = x;
}
}
cout << dp[n - 1] << endl;
}
int main()
{
vector< int > heights = { 10, 30, 40, 50, 20 };
int n = heights.size();
int k = 3;
minCost(heights, n, k);
return 0;
}
|
Java
import java.io.*;
class GFG {
static void minCost( int [] heights, int n, int k)
{
int [] dp = new int [n + 1 ];
dp[ 0 ] = 0 ;
dp[ 1 ] = Math.abs(heights[ 0 ] - heights[ 1 ]);
for ( int i = 2 ; i <= Math.min(n, k); i++) {
int x = Integer.MAX_VALUE;
for ( int j = 0 ; j < i; j++) {
if ((Math.abs(heights[i] - heights[j])
+ dp[j])
< x) {
x = Math.abs(heights[i] - heights[j])
+ dp[j];
}
}
dp[i] = x;
}
if (k < n) {
for ( int i = k + 1 ; i < n; i++) {
int x = Integer.MAX_VALUE;
for ( int j = (i - k); j < i; j++) {
if ((Math.abs(heights[i] - heights[j])
+ dp[j])
< x) {
x = Math.abs(heights[i]
- heights[j])
+ dp[j];
}
}
dp[i] = x;
}
}
System.out.println(dp[n - 1 ]);
}
public static void main(String[] args)
{
int [] heights = { 10 , 30 , 40 , 50 , 20 };
int n = heights.length;
int k = 3 ;
minCost(heights, n, k);
}
}
|
Python3
def minCost(heights, n, k):
dp = [ 0 ] * (n + 1 )
dp[ 0 ] = 0
dp[ 1 ] = abs (heights[ 0 ] - heights[ 1 ])
for i in range ( 2 , min (n, k) + 1 ):
x = float ( 'inf' )
for j in range (i):
if (( abs (heights[i] - heights[j]) + dp[j])
< x):
x = abs (heights[i] - heights[j]) + dp[j]
dp[i] = x
if (k < n):
for i in range (k + 1 , n):
x = float ( 'inf' )
for j in range (i - k, i):
if (( abs (heights[i] - heights[j]) + dp[j])
< x):
x = abs (heights[i] - heights[j]) + dp[j]
dp[i] = x
print (dp[n - 1 ])
heights = [ 10 , 30 , 40 , 50 , 20 ]
n = len (heights)
k = 3
minCost(heights, n, k)
|
C#
using System;
using System.Collections.Generic;
public class Gfg {
static void minCost(List< int > heights, int n, int k) {
List< int > dp = new List< int >(n + 1);
dp.Add(0);
dp.Add(Math.Abs(heights[0] - heights[1]));
for ( int i = 2; i <= Math.Min(n, k); i++) {
int x = int .MaxValue;
for ( int j = 0; j < i; j++) {
if ((Math.Abs(heights[i] - heights[j]) + dp[j]) < x) {
x = Math.Abs(heights[i] - heights[j]) + dp[j];
}
}
dp.Add(x);
}
if (k < n) {
for ( int i = k + 1; i < n; i++) {
int x = int .MaxValue;
for ( int j = (i - k); j < i; j++) {
if ((Math.Abs(heights[i] - heights[j]) + dp[j]) < x) {
x = Math.Abs(heights[i] - heights[j]) + dp[j];
}
}
dp.Add(x);
}
}
Console.WriteLine(dp[n - 1]);
}
static void Main() {
List< int > heights = new List< int > { 10, 30, 40, 50, 20 };
int n = heights.Count;
int k = 3;
minCost(heights, n, k);
}
}
|
Javascript
function minCost(heights, n, k) {
let dp = new Array(n + 1);
dp[0] = 0;
dp[1] = Math.abs(heights[0] - heights[1]);
for (let i = 2; i <= Math.min(n, k); i++) {
let x = Number.MAX_SAFE_INTEGER;
for (let j = 0; j < i; j++) {
if ((Math.abs(heights[i] - heights[j]) + dp[j])
< x) {
x = Math.abs(heights[i] - heights[j]) + dp[j];
}
}
dp[i] = x;
}
if (k < n) {
for (let i = k + 1; i < n; i++) {
let x = Number.MAX_SAFE_INTEGER;
for (let j = (i - k); j < i; j++) {
if ((Math.abs(heights[i] - heights[j]) + dp[j])
< x) {
x = Math.abs(heights[i] - heights[j])
+ dp[j];
}
}
dp[i] = x;
}
}
console.log(dp[n - 1]);
}
let heights = [10, 30, 40, 50, 20];
let n = heights.length;
let k = 3;
minCost(heights, n, k);
|
Time Complexity: O(n*k)
Auxiliary Space: O(n+1)
Approach 2: Using the Hash Table
The hash table is used to store the minimum cost for each height reached, allowing for efficient retrieval and updating of costs during the iteration.
Steps involved in the implementation of code:
- Initialize a hash table dp and setting the first and height and cost of zero.
- Iterate over the heights from the second height to the last height.
- Initialize a variable min_cost till the infinity.
- Iterate over the previous heights and calculate the cost of getting to the current height from each of these previous heights.
- Update the min_cost to the minimum cost found in just above step.
- Store the minimum cost in the hash table dp for the current value of height.
- Return the minimum cost from the hash table for the last height.
Below is the implementation of the above approach:
C++
#include <iostream>
#include <vector>
#include <unordered_map>
#include <cmath>
#include <limits>
using std::cout;
using std::endl;
using std::vector;
using std::unordered_map;
using std::min;
using std:: abs ;
using std::numeric_limits;
int minCost( const vector< int >& heights, int n, int k) {
unordered_map< int , int > dp;
dp[heights[0]] = 0;
for ( int i = 1; i < n; i++) {
int min_cost = numeric_limits< int >::max();
for ( int j = i-1; j >= std::max(0, i-k); j--) {
int cost = dp[heights[j]] + abs (heights[i]-heights[j]);
min_cost = min(min_cost, cost);
}
dp[heights[i]] = min_cost;
}
return dp[heights[n-1]];
}
int main() {
vector< int > heights = { 10, 30, 40, 50, 20 };
int n = heights.size();
int k = 3;
int cost = minCost(heights, n, k);
cout << cost << endl;
return 0;
}
|
Java
import java.util.HashMap;
import java.util.Map;
public class Main {
public static int minCost( int [] heights, int n, int k) {
Map<Integer, Integer> dp = new HashMap<>();
dp.put(heights[ 0 ], 0 );
for ( int i = 1 ; i < n; i++) {
int minCost = Integer.MAX_VALUE;
for ( int j = i - 1 ; j >= Math.max( 0 , i - k); j--) {
int cost = dp.get(heights[j]) + Math.abs(heights[i] - heights[j]);
minCost = Math.min(minCost, cost);
}
dp.put(heights[i], minCost);
}
return dp.get(heights[n - 1 ]);
}
public static void main(String[] args) {
int [] heights = { 10 , 30 , 40 , 50 , 20 };
int n = heights.length;
int k = 3 ;
int cost = minCost(heights, n, k);
System.out.println(cost);
}
}
|
Python3
def min_cost(heights, k):
dp = {}
dp[heights[ 0 ]] = 0
for i in range ( 1 , len (heights)):
min_cost = float ( 'inf' )
for j in range (i - 1 , max ( 0 , i - k) - 1 , - 1 ):
cost = dp[heights[j]] + abs (heights[i] - heights[j])
min_cost = min (min_cost, cost)
dp[heights[i]] = min_cost
return dp[heights[ - 1 ]]
if __name__ = = "__main__" :
heights = [ 10 , 30 , 40 , 50 , 20 ]
k = 3
cost = min_cost(heights, k)
print (cost)
|
C#
using System;
using System.Collections.Generic;
class Program
{
public static int MinCost( int [] heights, int n, int k)
{
Dictionary< int , int > dp = new Dictionary< int , int >();
dp[heights[0]] = 0;
for ( int i = 1; i < n; i++)
{
int minCost = int .MaxValue;
for ( int j = i - 1; j >= Math.Max(0, i - k); j--)
{
int cost = dp[heights[j]] + Math.Abs(heights[i] - heights[j]);
minCost = Math.Min(minCost, cost);
}
dp[heights[i]] = minCost;
}
return dp[heights[n - 1]];
}
public static void Main( string [] args)
{
int [] heights = { 10, 30, 40, 50, 20 };
int n = heights.Length;
int k = 3;
int cost = MinCost(heights, n, k);
Console.WriteLine(cost);
}
}
|
Javascript
function minCost( heights, n, k) {
let dp=[];
dp[heights[0]] = 0;
for (let i = 1; i < n; i++) {
let min_cost = Number.MAX_VALUE;
for (let j = i-1; j >= Math.max(0, i-k); j--) {
let cost = dp[heights[j]] + Math.abs(heights[i]-heights[j]);
min_cost = Math.min(min_cost, cost);
}
dp[heights[i]] = min_cost;
}
return dp[heights[n-1]];
}
let heights = [ 10, 30, 40, 50, 20 ];
let n = heights.length;
let k = 3;
let cost = minCost(heights, n, k);
console.log(cost);
|
Output:
30
Time Complexity: O(n*k), as we are computing the cost of reaching each stone from all previous stones that are within the maximum jump limit k.
Auxiliary Space: O(n), as we are using the hash table to store the minimum cost to reach at every stone.
Share your thoughts in the comments
Please Login to comment...