Open In App

Minimum Cost to Reach the Top

Last Updated : 11 Jul, 2025
Comments
Improve
Suggest changes
19 Likes
Like
Report

Given an array of integers cost[] of length n, where cost[i] is the cost of the ith step on a staircase. Once the cost is paid, we can either climb one or two steps.
We can either start from the step with index 0, or the step with index 1. The task is to find the minimum cost to reach the top.

Examples: 

Input: cost[] = [10, 15, 20]
Output: 15
Explanation: The cheapest option is to start from step with index 1, pay cost[1] and go to the top.

Climbing-Stairs-1


Input: cost[] = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1]
Output:
Explanation: The cheapest option is to start from step with index 1on cost[0], and only step on 1s, skipping cost[3].

Climbing-Stairs-2

[Naive Approach] Using Recursion - O(2^n) Time and O(n) Space

This problem is an extension of problem: Climbing Stairs to reach at the top.

There are n stairs, and a person is allowed to climb 1 or 2 stairs. If a person is standing at i-th stair, the person can move to i+1, i+2, stair. A recursive function can be formed where at current index i the function is recursively called for i+1, i+2 th stair. 
There is another way of forming the recursive function. To reach a stair i, a person has to jump either from i-1, or i-2 th stair.

  • minCost(n) = cost[i] + min(minCost(n-1) , minCost(n-2))
C++
// C++ program to count number of
// ways to reach nth stair.
#include <bits/stdc++.h>
using namespace std;

int minCostRecur(int i, vector<int> &cost) {
    
    // Base case
    if (i==0 || i==1) {
        return cost[i];
    }
    
    return cost[i] + min(minCostRecur(i-1, cost), 
                         minCostRecur(i-2, cost));
}

int minCostClimbingStairs(vector<int> &cost) {
    int n = cost.size();
    
    if (n==1) return cost[0];
    
    // Return minimum of cost to 
    // reach (n-1)th stair and 
    // cost to reach (n-2)th stair
    return min(minCostRecur(n-1, cost), 
                minCostRecur(n-2, cost));
}

int main() {
	vector<int> cost = { 16, 19, 10, 12, 18 };
    cout << minCostClimbingStairs(cost) << endl;
	return 0;
}
Java
// Java program to count number of
// ways to reach nth stair.
import java.util.*;

class GfG {

    static int minCostRecur(int i, int[] cost) {
        
        // Base case
        if (i == 0 || i == 1) {
            return cost[i];
        }
        
        return cost[i] + Math.min(minCostRecur(i - 1, cost), 
                                  minCostRecur(i - 2, cost));
    }

    static int minCostClimbingStairs(int[] cost) {
        int n = cost.length;
        
        if (n == 1) return cost[0];
        
        // Return minimum of cost to  
        // reach (n-1)th stair and  
        // cost to reach (n-2)th stair
        return Math.min(minCostRecur(n - 1, cost), 
                        minCostRecur(n - 2, cost));
    }

    public static void main(String[] args) {
        int[] cost = { 16, 19, 10, 12, 18 };
        System.out.println(minCostClimbingStairs(cost));
    }
}
Python
# Python program to count number of 
# ways to reach nth stair.

def minCostRecur(i, cost):
    
    # Base case
    if i == 0 or i == 1:
        return cost[i]
    
    return cost[i] + min(minCostRecur(i - 1, cost), 
                         minCostRecur(i - 2, cost))

def minCostClimbingStairs(cost):
    n = len(cost)
    
    if n == 1:
        return cost[0]
    
    # Return minimum of cost to 
    # reach (n-1)th stair and 
    # cost to reach (n-2)th stair
    return min(minCostRecur(n - 1, cost), 
               minCostRecur(n - 2, cost))

if __name__ == "__main__":
    cost = [16, 19, 10, 12, 18]
    print(minCostClimbingStairs(cost))
C#
// C# program to count number of
// ways to reach nth stair.

using System;

class GfG {

    static int minCostRecur(int i, int[] cost) {
        
        // Base case
        if (i == 0 || i == 1) {
            return cost[i];
        }
        
        return cost[i] + Math.Min(minCostRecur(i - 1, cost), 
                                  minCostRecur(i - 2, cost));
    }

    static int minCostClimbingStairs(int[] cost) {
        int n = cost.Length;
        
        if (n == 1) return cost[0];
        
        // Return minimum of cost to reach (n-1)th   
        // stair and cost to reach (n-2)th stair
        return Math.Min(minCostRecur(n - 1, cost), 
                        minCostRecur(n - 2, cost));
    }

    static void Main(string[] args) {
        int[] cost = { 16, 19, 10, 12, 18 };
        Console.WriteLine(minCostClimbingStairs(cost));
    }
}
JavaScript
// JavaScript program to count number of
// ways to reach nth stair.
function minCostRecur(i, cost) {
    
    // Base case
    if (i === 0 || i === 1) {
        return cost[i];
    }
    
    return cost[i] + Math.min(minCostRecur(i - 1, cost), 
                              minCostRecur(i - 2, cost));
}

function minCostClimbingStairs(cost) {
    let n = cost.length;
    
    if (n === 1) return cost[0];
    
    // Return minimum of cost to reach (n-1)th stair and  
    // cost to reach (n-2)th stair
    return Math.min(minCostRecur(n - 1, cost), 
                    minCostRecur(n - 2, cost));
}

// Driver Code
let cost = [16, 19, 10, 12, 18];
console.log(minCostClimbingStairs(cost));

Output
31

[Better Approach 1] Using Top-Down DP (Memoization) – O(n) Time and O(n) Space

If we notice carefully, we can observe that the above recursive solution holds the following two properties of Dynamic Programming:

1. Optimal Substructure: Minimum cost to reach the nth stair, i.e., minCost(n), depends on the optimal solutions of the subproblems minCost(n-1) , and minCost(n-2). By choosing the minimum of these optimal substructures, we can efficiently calculate the minimum cost to reach the nth stair.

2. Overlapping Subproblems: While applying a recursive approach in this problem, we notice that certain subproblems are computed multiple times. For example, when calculating minCost(4), we recursively calculate minCost(3) and minCost(2) which in turn will recursively compute minCost(2) again. This redundancy leads to overlapping subproblems.

  • There is only one parameter that changes in the recursive solution and it can go from 0 to n. So we create a 1D array of size n+1 for memoization.
  • We initialize this array as -1 to indicate nothing is computed initially.
  • Now we modify our recursive solution to first check if the value is -1, then only make recursive calls. This way, we avoid re-computations of the same subproblems.
C++
// C++ program to count number of
// ways to reach nth stair.
#include <bits/stdc++.h>
using namespace std;

int minCostRecur(int i, vector<int> &cost, vector<int> &memo) {
    
    // Base case
    if (i==0 || i==1) {
        return cost[i];
    }
    
    // If value is memoized
    if (memo[i]!=-1) return memo[i];
    
    return memo[i] = cost[i] + 
    min(minCostRecur(i-1, cost, memo), 
    minCostRecur(i-2, cost, memo));
}

int minCostClimbingStairs(vector<int> &cost) {
    int n = cost.size();
    
    if (n==1) return cost[0];
    
    vector<int> memo(n, -1);
    
    // Return minimum of cost to 
    // climb (n-1)th stair and 
    // cost to reach (n-2)th stair
    return min(minCostRecur(n-1, cost, memo), 
               minCostRecur(n-2, cost, memo));
}

int main() {
	vector<int> cost = { 16, 19, 10, 12, 18 };
    cout << minCostClimbingStairs(cost) << endl;
	return 0;
}
Java
// Java program to count number of
// ways to reach nth stair.
import java.util.*;

class GfG {

    static int minCostRecur(int i, int[] cost, int[] memo) {
        
        // Base case
        if (i == 0 || i == 1) {
            return cost[i];
        }
        
        // If value is memoized
        if (memo[i] != -1) return memo[i];
        
        return memo[i] = cost[i] + 
        Math.min(minCostRecur(i - 1, cost, memo), 
        minCostRecur(i - 2, cost, memo));
    }

    static int minCostClimbingStairs(int[] cost) {
        int n = cost.length;
        
        if (n == 1) return cost[0];
        
        int[] memo = new int[n];
        Arrays.fill(memo, -1);
        
        // Return minimum of cost to  
        // climb (n-1)th stair and  
        // cost to reach (n-2)th stair
        return Math.min(minCostRecur(n - 1, cost, memo), 
                        minCostRecur(n - 2, cost, memo));
    }

    public static void main(String[] args) {
        int[] cost = { 16, 19, 10, 12, 18 };
        System.out.println(minCostClimbingStairs(cost));
    }
}
Python
# Python program to count number of 
# ways to reach nth stair.

def minCostRecur(i, cost, memo):
    
    # Base case
    if i == 0 or i == 1:
        return cost[i]
    
    # If value is memoized
    if memo[i] != -1:
        return memo[i]
    
    memo[i] = cost[i] + min(minCostRecur(i - 1, cost, memo), 
    minCostRecur(i - 2, cost, memo))
    return memo[i]

def minCostClimbingStairs(cost):
    n = len(cost)
    
    if n == 1:
        return cost[0]
    
    memo = [-1] * n
    
    # Return minimum of cost to 
    # climb (n-1)th stair and 
    # cost to reach (n-2)th stair
    return min(minCostRecur(n - 1, cost, memo), 
               minCostRecur(n - 2, cost, memo))

if __name__ == "__main__":
    cost = [16, 19, 10, 12, 18]
    print(minCostClimbingStairs(cost))
C#
// C# program to count number of
// ways to reach nth stair.
using System;

class GfG {

    static int minCostRecur(int i, int[] cost, int[] memo) {
        
        // Base case
        if (i == 0 || i == 1) {
            return cost[i];
        }
        
        // If value is memoized
        if (memo[i] != -1) return memo[i];
        
        return memo[i] = cost[i] + 
                         Math.Min(minCostRecur(i - 1, cost, memo), 
                                  minCostRecur(i - 2, cost, memo));
    }

    static int minCostClimbingStairs(int[] cost) {
        int n = cost.Length;
        
        if (n == 1) return cost[0];
        
        int[] memo = new int[n];
        for (int i = 0; i < n; i++) memo[i] = -1;
        
        // Return minimum of cost to  
        // climb (n-1)th stair and  
        // cost to reach (n-2)th stair
        return Math.Min(minCostRecur(n - 1, cost, memo), 
                        minCostRecur(n - 2, cost, memo));
    }

    static void Main(string[] args) {
        int[] cost = { 16, 19, 10, 12, 18 };
        Console.WriteLine(minCostClimbingStairs(cost));
    }
}
JavaScript
// JavaScript program to count number of
// ways to reach nth stair.

function minCostRecur(i, cost, memo) {
    
    // Base case
    if (i === 0 || i === 1) {
        return cost[i];
    }
    
    // If value is memoized
    if (memo[i] !== -1) return memo[i];
    
    memo[i] = cost[i] + Math.min(minCostRecur(i - 1, cost, memo), 
                                 minCostRecur(i - 2, cost, memo));
    return memo[i];
}

function minCostClimbingStairs(cost) {
    let n = cost.length;
    
    if (n === 1) return cost[0];
    
    let memo = new Array(n).fill(-1);
    
    // Return minimum of cost to  
    // climb (n-1)th stair and  
    // cost to reach (n-2)th stair
    return Math.min(minCostRecur(n - 1, cost, memo), 
                    minCostRecur(n - 2, cost, memo));
}

let cost = [16, 19, 10, 12, 18];
console.log(minCostClimbingStairs(cost));

Output
31

[Better Approach 2] Using Bottom-Up DP (Tabulation) - O(n) Time and O(n) Space

The idea is to create a1-D array, fill values for first two stairs and compute the values from 2 to n using the previous two results. For i = 2 to n, do dp[i] = cost[i] + min(dp[i-1] + dp[i-2]).

Illustration:


C++
// C++ program to count number of
// ways to reach nth stair.
#include <bits/stdc++.h>
using namespace std;

int minCostClimbingStairs(vector<int> &cost) {
    int n = cost.size();
    
    if (n==1) return cost[0];
    
    vector<int> dp(n);
    dp[0] = cost[0];
    dp[1] = cost[1];
    
    for (int i=2; i<n; i++) {
        dp[i] = cost[i] + min(dp[i-1], dp[i-2]);
    }
    
    // Return minimum of cost to 
    // climb (n-1)th stair and 
    // cost to reach (n-2)th stair
    return min(dp[n-1], dp[n-2]);
}

int main() {
	vector<int> cost = { 16, 19, 10, 12, 18 };
    cout << minCostClimbingStairs(cost) << endl;
	return 0;
}
Java
// Java program to count number of
// ways to reach nth stair.
import java.util.*;

class GfG {

    static int minCostClimbingStairs(int[] cost) {
        int n = cost.length;
        
        if (n == 1) return cost[0];
        
        int[] dp = new int[n];
        dp[0] = cost[0];
        dp[1] = cost[1];
        
        for (int i = 2; i < n; i++) {
            dp[i] = cost[i] + Math.min(dp[i - 1], dp[i - 2]);
        }
        
        // Return minimum of cost to  
        // climb (n-1)th stair and  
        // cost to reach (n-2)th stair
        return Math.min(dp[n - 1], dp[n - 2]);
    }

    public static void main(String[] args) {
        int[] cost = { 16, 19, 10, 12, 18 };
        System.out.println(minCostClimbingStairs(cost));
    }
}
Python
# Python program to count number of 
# ways to reach nth stair.

def minCostClimbingStairs(cost):
    n = len(cost)
    
    if n == 1:
        return cost[0]
    
    dp = [0] * n
    dp[0] = cost[0]
    dp[1] = cost[1]
    
    for i in range(2, n):
        dp[i] = cost[i] + min(dp[i - 1], dp[i - 2])
    
    # Return minimum of cost to 
    # climb (n-1)th stair and 
    # cost to reach (n-2)th stair
    return min(dp[n - 1], dp[n - 2])

if __name__ == "__main__":
    cost = [16, 19, 10, 12, 18]
    print(minCostClimbingStairs(cost))
C#
// C# program to count number of
// ways to reach nth stair.

using System;

class GfG {

    static int minCostClimbingStairs(int[] cost) {
        int n = cost.Length;
        
        if (n == 1) return cost[0];
        
        int[] dp = new int[n];
        dp[0] = cost[0];
        dp[1] = cost[1];
        
        for (int i = 2; i < n; i++) {
            dp[i] = cost[i] + Math.Min(dp[i - 1], dp[i - 2]);
        }
        
        // Return minimum of cost to  
        // climb (n-1)th stair and  
        // cost to reach (n-2)th stair
        return Math.Min(dp[n - 1], dp[n - 2]);
    }

    static void Main(string[] args) {
        int[] cost = { 16, 19, 10, 12, 18 };
        Console.WriteLine(minCostClimbingStairs(cost));
    }
}
JavaScript
// JavaScript program to count number of
// ways to reach nth stair.

function minCostClimbingStairs(cost) {
    let n = cost.length;
    
    if (n === 1) return cost[0];
    
    let dp = new Array(n);
    dp[0] = cost[0];
    dp[1] = cost[1];
    
    for (let i = 2; i < n; i++) {
        dp[i] = cost[i] + Math.min(dp[i - 1], dp[i - 2]);
    }
    
    // Return minimum of cost to  
    // climb (n-1)th stair and  
    // cost to reach (n-2)th stair
    return Math.min(dp[n - 1], dp[n - 2]);
}

let cost = [16, 19, 10, 12, 18];
console.log(minCostClimbingStairs(cost));

Output
31

[Expected Approach] Using Space Optimized DP – O(n) Time and O(1) Space

The idea is to store only the previous two computed values. We can observe that for a given stair, only the result of last two stairs are needed. So only store these two values and update them after each step.

C++
// C++ program to count number of
// ways to reach nth stair.
#include <bits/stdc++.h>
using namespace std;

int minCostClimbingStairs(vector<int> &cost) {
    int n = cost.size();
    
    if (n==1) return cost[0];

    int prev2 = cost[0];
    int prev1 = cost[1];
    
    for (int i=2; i<n; i++) {
        int curr = cost[i] + 
        min(prev1, prev2);
        
        prev2 = prev1;
        prev1 = curr;
    }
    
    // Return minimum of cost to 
    // climb (n-1)th stair and 
    // cost to reach (n-2)th stair
    return min(prev1, prev2);
}

int main() {
	vector<int> cost = { 16, 19, 10, 12, 18 };
    cout << minCostClimbingStairs(cost) << endl;
	return 0;
}
Java
// Java program to count number of
// ways to reach nth stair.

import java.util.*;

class GfG {

    static int minCostClimbingStairs(int[] cost) {
        int n = cost.length;
        
        if (n == 1) return cost[0];

        int prev2 = cost[0];
        int prev1 = cost[1];
        
        for (int i = 2; i < n; i++) {
            int curr = cost[i] + Math.min(prev1, prev2);
            prev2 = prev1;
            prev1 = curr;
        }
        
        // Return minimum of cost to  
        // climb (n-1)th stair and  
        // cost to reach (n-2)th stair
        return Math.min(prev1, prev2);
    }

    public static void main(String[] args) {
        int[] cost = { 16, 19, 10, 12, 18 };
        System.out.println(minCostClimbingStairs(cost));
    }
}
Python
# Python program to count number of 
# ways to reach nth stair.

def minCostClimbingStairs(cost):
    n = len(cost)
    
    if n == 1:
        return cost[0]

    prev2 = cost[0]
    prev1 = cost[1]
    
    for i in range(2, n):
        curr = cost[i] + min(prev1, prev2)
        prev2 = prev1
        prev1 = curr
    
    # Return minimum of cost to 
    # climb (n-1)th stair and 
    # cost to reach (n-2)th stair
    return min(prev1, prev2)

if __name__ == "__main__":
    cost = [16, 19, 10, 12, 18]
    print(minCostClimbingStairs(cost))
C#
// C# program to count number of
// ways to reach nth stair.

using System;

class GfG {

    static int minCostClimbingStairs(int[] cost) {
        int n = cost.Length;
        
        if (n == 1) return cost[0];

        int prev2 = cost[0];
        int prev1 = cost[1];
        
        for (int i = 2; i < n; i++) {
            int curr = cost[i] + Math.Min(prev1, prev2);
            prev2 = prev1;
            prev1 = curr;
        }
        
        // Return minimum of cost to  
        // climb (n-1)th stair and  
        // cost to reach (n-2)th stair
        return Math.Min(prev1, prev2);
    }

    static void Main(string[] args) {
        int[] cost = { 16, 19, 10, 12, 18 };
        Console.WriteLine(minCostClimbingStairs(cost));
    }
}
JavaScript
// JavaScript program to count number of
// ways to reach nth stair.
function minCostClimbingStairs(cost) {
    let n = cost.length;
    
    if (n === 1) return cost[0];

    let prev2 = cost[0];
    let prev1 = cost[1];
    
    for (let i = 2; i < n; i++) {
        let curr = cost[i] + Math.min(prev1, prev2);
        prev2 = prev1;
        prev1 = curr;
    }
    
    // Return minimum of cost to  
    // climb (n-1)th stair and  
    // cost to reach (n-2)th stair
    return Math.min(prev1, prev2);
}

let cost = [16, 19, 10, 12, 18];
console.log(minCostClimbingStairs(cost));

Output
31

Article Tags :

Explore