A person is at the bottom of a staircase with n steps. They can climb up to m steps at a time. The goal is to determine how many unique ways the person can reach the top of the staircase. The number of steps n and the maximum steps they can climb at a time m are given as inputs.
Input: n =5, m =3Output: 13Explanation:
The person can reach the top in the following ways:1-1-1-1-1,1-1-1-2,1-1-2-1,1-2-1-1,2-1-1-1,2-2-1,2-1-2,1-2-2,3-1-1,3-2,1-3-1,1-1-3,3.Total =13 ways.
A person is at the bottom of a staircase with n steps. They can climb up to m steps at a time. The goal is to determine how many unique ways the person can reach the top of the staircase. The number of steps (n) and the maximum steps they can climb at a time (m) are given as inputs.
#include<iostream>usingnamespace std;
classSolution {
public:int countWays(int n, int m) {
// Base cases
if (n ==0)
return1;
if (n <0)
return0;
// Recursive calculation
int total =0;
for (int i =1; i <= m; i++) {
total += countWays(n - i, m);
}
return total;
}
};
// Example usage
intmain() {
Solution solution;
cout << solution.countWays(4, 2) << endl; // Output: 5
return0;
}
classSolution {
publicintcountWays(int n, int m) {
// Base caseif (n == 0) {
return 1;
}
if (n < 0) {
return 0;
}
// Recursive calculationint total = 0;
for (int i = 1; i <= m; i++) {
total += countWays(n - i, m);
}
return total;
}
// Example usagepublicstaticvoidmain(String[] args) {
Solution solution =new Solution();
System.out.println(solution.countWays(4, 2)); // Output: 5 }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
classSolution:
defcountWays(self, n: int, m: int) -> int:
# Base casesif n ==0:
return1if n <0:
return0# Recursive calculation total =0for i in range(1, m +1):
total += self.countWays(n - i, m)
return total
# Example usagesolution = Solution()
print(solution.countWays(4, 2)) # Output: 5
The top-down approach uses memoisation to optimise the naive recursive approach. This method avoids recalculating the solutions for subproblems by storing previously computed results in a dictionary or array.
#include<iostream>#include<unordered_map>usingnamespace std;
classSolution {
public:int countWays(int n, int m, unordered_map<int, int>& memo) {
// Base cases
if (n ==0)
return1;
if (n <0)
return0;
// Check memoisation table
if (memo.find(n) != memo.end())
return memo[n];
// Recursive calculation with memoisation
int total =0;
for (int i =1; i <= m; i++) {
total += countWays(n - i, m, memo);
}
memo[n] = total; // Store result in the memo
return memo[n];
}
};
intmain() {
Solution solution;
unordered_map<int, int> memo;
cout << solution.countWays(4, 2, memo) << endl; // Output: 5
return0;
}
import java.util.HashMap;
classSolution {
publicintcountWays(int n, int m, HashMap<Integer, Integer> memo) {
// Base casesif (n == 0) {
return 1;
}
if (n < 0) {
return 0;
}
// Check the memoisation tableif (memo.containsKey(n)) {
return memo.get(n);
}
// Recursive calculation with memoisationint total = 0;
for (int i = 1; i <= m; i++) {
total += countWays(n - i, m, memo);
}
memo.put(n, total); // Store result in the memoreturn total;
}
// Example usagepublicstaticvoidmain(String[] args) {
Solution solution =new Solution();
HashMap<Integer, Integer> memo =new HashMap<>();
System.out.println(solution.countWays(4, 2, memo)); // Output: 5 }
}
classSolution:
defcountWays(self, n: int, m: int, memo=None) -> int:
if memo isNone:
memo = {}
# Base casesif n ==0:
return1if n <0:
return0# Check memoisation tableif n in memo:
return memo[n]
# Recursive calculation with memoisation total =0for i in range(1, m +1):
total += self.countWays(n - i, m, memo)
memo[n] = total # Store result in the memoreturn total
# Example usagesolution = Solution()
print(solution.countWays(4, 2)) # Output: 5
This is a variation of the “staircase problem” and can be solved using dynamic programming. The reasoning proceeds as follows:
The problem can be broken down into subproblems: to determine the ways to reach the top of n steps, consider how the person can arrive there using 1, 2, …, or up to m steps.
To determine ways to reach step n, sum up the number of ways to reach steps n-1, n-2, …, n-m.
We use dynamic programming because the problem exhibits both overlapping subproblems (repeated computation for the same value of n) and optimal substructure (solution of the larger problem depends on smaller subproblems).
Steps:
Create a dp array where dp[i] represents the number of ways to climb i steps.
Initialise dp[0] = 1 (1 way to stay on ground).
For each step i from 1 to n:
Calculate dp[i] by summing dp[i-1] to dp[i-m] (only considering valid indices).
#include<iostream>#include<vector>usingnamespace std;
classSolution {
public:int countWays(int n, int m) {
// Edge case
if (n ==0)
return1;
// Create a DP array to store the number of ways to reach each step
vector<int> dp(n +1, 0);
dp[0] =1; // Base case: 1 way to stay on ground
// Populate the DP array
for (int i =1; i <= n; i++) {
for (int j =1; j <= min(m, i); j++) {
dp[i] += dp[i - j];
}
}
// Result is in dp[n]
return dp[n];
}
};
// Example usage
intmain() {
Solution solution;
cout << solution.countWays(4, 2) << endl; // Output: 5
return0;
}
classSolution {
publicintcountWays(int n, int m) {
// Edge caseif (n == 0)
return 1;
// Create a DP array to store the number of ways to reach each stepint[] dp =newint[n + 1];
dp[0]= 1; // Base case: 1 way to stay on ground// Populate the dp arrayfor (int i = 1; i <= n; i++) {
for (int j = 1; j <= Math.min(m, i); j++) {
dp[i]+= dp[i - j];
}
}
// Result is in dp[n]return dp[n];
}
// Example usagepublicstaticvoidmain(String[] args) {
Solution solution =new Solution();
System.out.println(solution.countWays(4, 2)); // Output: 5 }
}
classSolution:
defcountWays(self, n: int, m: int) -> int:
# Edge caseif n ==0:
return1# Create a DP array to store the number of ways to reach each step dp = [0] * (n +1)
dp[0] =1# Base case: 1 way to stand on ground# Populate the dp arrayfor i in range(1, n +1):
for j in range(1, min(m, i) +1):
dp[i] += dp[i - j]
# Result is in dp[n]return dp[n]
# Example usagesolution = Solution()
print(solution.countWays(4, 2)) # Output: 5