Count ways to reach the n'th stair - GeeksforGeeks

22 Apr, 2022
There are n stairs, a person standing at the bottom wants to reach the top. The person can climb either 1 stair or 2 stairs at a time. Count the number of ways, the person can reach the top. 
Consider the example shown in the diagram. The value of n is 3. There are 3 ways to reach the top. The diagram is taken from Easier Fibonacci puzzles
Examples: 
Input: n = 1
Output: 1
There is only one way to climb 1 stair

Input: n = 2
Output: 2
There are two ways: (1, 1) and (2)

Input: n = 4
Output: 5
(1, 1, 1, 1), (1, 1, 2), (2, 1, 1), (1, 2, 1), (2, 2) 
Method 1: The first method uses the technique of recursion to solve this problem.Approach: We can easily find the recursive nature in the above problem. The person can reach nth stair from either (n-1)th stair or from (n-2)th stair. Hence, for each stair n, we try to find out the number of ways to reach n-1th stair and n-2th stair and add them to give the answer for the nth stair. Therefore the expression for such an approach comes out to be : 
ways(n) = ways(n-1) + ways(n-2)
The above expression is actually the expression for Fibonacci numbers, but there is one thing to notice, the value of ways(n) is equal to fibonacci(n+1). 
ways(1) = fib(2) = 1
ways(2) = fib(3) = 2
ways(3) = fib(4) = 3
For a better understanding, let’s refer to the recursion tree below -: 
Input: N = 4

                  fib(5)
           '3'  /        \   '2'
               /          \
           fib(4)         fib(3)
     '2'  /      \ '1'   /      \  
         /        \     /        \ 
     fib(3)     fib(2)fib(2)      fib(1) 
     /    \ '1' /   \ '0'
'1' /   '1'\   /     \ 
   /        \ fib(1) fib(0) 
fib(2)     fib(1)
So we can use the function for Fibonacci numbers to find the value of ways(n). Following is C++ implementation of the above idea. 
C++
C
Java
Python
C#
PHP
Javascript
// C++ program to count number of// ways to reach Nth stair#include <bits/stdc++.h>using namespace std; // A simple recursive program to// find N'th fibonacci numberint fib(int n){    if (n <= 1)        return n;    return fib(n - 1) + fib(n - 2);} // Returns number of ways to// reach s'th stairint countWays(int s){    return fib(s + 1);} // Driver Cint main(){    int s = 4;     cout << "Number of ways = " << countWays(s);     return 0;} // This code is contributed by shubhamsingh10
// C Program to count number of// ways to reach Nth stair#include <stdio.h> // A simple recursive program to// find n'th fibonacci numberint fib(int n){    if (n <= 1)        return n;    return fib(n - 1) + fib(n - 2);} // Returns number of ways to reach s'th stairint countWays(int s){    return fib(s + 1);} // Driver program to test above functionsint main(){    int s = 4;    printf("Number of ways = %d", countWays(s));    getchar();    return 0;}
class stairs {    // A simple recursive program to find    // n'th fibonacci number    static int fib(int n)    {        if (n <= 1)            return n;        return fib(n - 1) + fib(n - 2);    }     // Returns number of ways to reach s'th stair    static int countWays(int s)    {        return fib(s + 1);    }     /* Driver program to test above function */    public static void main(String args[])    {        int s = 4;        System.out.println("Number of ways = " + countWays(s));    }} /* This code is contributed by Rajat Mishra */
# Python program to count# ways to reach nth stair # Recursive function to find# Nth fibonacci numberdef fib(n):    if n <= 1:        return n    return fib(n-1) + fib(n-2) # Returns no. of ways to# reach sth stairdef countWays(s):    return fib(s + 1) # Driver programs = 4print "Number of ways = ",print countWays(s) # Contributed by Harshit Agrawal
// C# program to count the// number of ways to reach// n'th stairusing System; class GFG {    // A simple recursive    // program to find n'th    // fibonacci number    static int fib(int n)    {        if (n <= 1)            return n;        return fib(n - 1) + fib(n - 2);    }     // Returns number of ways    // to reach s'th stair    static int countWays(int s)    {        return fib(s + 1);    }     // Driver Code    static public void Main()    {        int s = 4;        Console.WriteLine("Number of ways = " + countWays(s));    }} // This code is contributed// by akt_mit
<?php// A PHP program to count// number of ways to reach// n'th stair when a person// can climb 1, 2, ..m stairs// at a time. // A simple recursive// function to find n'th// fibonacci numberfunction fib($n){if ($n <= 1)    return $n;return fib($n - 1) +       fib($n - 2);} // Returns number of// ways to reach s'th stairfunction countWays($s){    return fib($s + 1);} // Driver Code$s = 4;echo "Number of ways = ",           countWays($s); // This code is contributed// by m_kit?>
<script>// A Javascript program to count// number of ways to reach// n'th stair when a person// can climb 1, 2, ..m stairs// at a time. // A simple recursive// function to find n'th// fibonacci numberfunction fib(n){if (n <= 1)    return n;return fib(n - 1) +       fib(n - 2);} // Returns number of// ways to reach s'th stairfunction countWays(s){    return fib(s + 1);} // Driver Codelet s = 4;document.write("Number of ways = " + countWays(s)); // This code is contributed// by _saurabh_jaiswal</script>
Number of ways = 5
Complexity Analysis: 
Time Complexity: O(2^n) The time complexity of the above implementation is exponential (golden ratio raised to power n) due to redundant calculations.It can be optimized to work in O(Logn) time using the previously discussed Fibonacci function optimizations.
Auxiliary Space: O(1)
Generalization of the Problem How to count the number of ways if the person can climb up to m stairs for a given value m. For example, if m is 4, the person can climb 1 stair or 2 stairs or 3 stairs or 4 stairs at a time.
Approach: For the generalization of above approach the following recursive relation can be used. 
ways(n, m) = ways(n-1, m) + ways(n-2, m) + ... ways(n-m, m) 
In this approach to reach nth stair, try climbing all possible number of stairs lesser than equal to n from present stair.
Following is the implementation of above recurrence. 
C++
C
Java
Python
C#
PHP
Javascript
// C++ program to count number of ways// to reach nth stair when a person// can climb either 1 or 2 stairs at a time#include <bits/stdc++.h>using namespace std; // A recursive function used by countWaysint countWaysUtil(int n, int m){    if (n <= 1)    {        return n;    }         int res = 0;    for(int i = 1; i <= m && i <= n; i++)    {       res += countWaysUtil(n - i, m);    }    return res;} // Returns number of ways to reach s'th stairint countWays(int s, int m){    return countWaysUtil(s + 1, m);} // Driver codeint main(){    int s = 4, m = 2;    cout << "Number of ways = " << countWays(s, m);     return 0;} // This code is contribute by shubhamsingh10
// C program to count number of ways// to reach nth stair when a person// can climb either 1 or 2 stairs at a time#include <stdio.h> // A recursive function used by countWaysint countWaysUtil(int n, int m){    if (n <= 1)        return n;    int res = 0;    for (int i = 1; i <= m && i <= n; i++)        res += countWaysUtil(n - i, m);    return res;} // Returns number of ways to reach s'th stairint countWays(int s, int m){    return countWaysUtil(s + 1, m);} // Driver program to test above functions-int main(){    int s = 4, m = 2;    printf("Number of ways = %d", countWays(s, m));    return 0;}
class stairs {    // A recursive function used by countWays    static int countWaysUtil(int n, int m)    {        if (n <= 1)            return n;        int res = 0;        for (int i = 1; i <= m && i <= n; i++)            res += countWaysUtil(n - i, m);        return res;    }     // Returns number of ways to reach s'th stair    static int countWays(int s, int m)    {        return countWaysUtil(s + 1, m);    }     /* Driver program to test above function */    public static void main(String args[])    {        int s = 4, m = 2;        System.out.println("Number of ways = "                           + countWays(s, m));    }} /* This code is contributed by Rajat Mishra */
# A program to count the number of ways# to reach n'th stair # Recursive function used by countWaysdef countWaysUtil(n, m):    if n <= 1:        return n    res = 0    i = 1    while i<= m and i<= n:        res = res + countWaysUtil(n-i, m)        i = i + 1    return res     # Returns number of ways to reach s'th stair   def countWays(s, m):    return countWaysUtil(s + 1, m)      # Driver programs, m = 4, 2print "Number of ways =", countWays(s, m) # Contributed by Harshit Agrawal
using System;public class stairs{       // A recursive function used by countWays    static int countWaysUtil(int n, int m)    {        if (n <= 1)            return n;        int res = 0;        for (int i = 1; i <= m && i <= n; i++)            res += countWaysUtil(n - i, m);        return res;    }     // Returns number of ways to reach s'th stair    static int countWays(int s, int m)    {        return countWaysUtil(s + 1, m);    }     /* Driver program to test above function */    public static void Main(String []args)    {        int s = 4, m = 2;        Console.WriteLine("Number of ways = "                           + countWays(s, m));    }} // This code is contributed by umadevi9616
<?php// A PHP program to count// number of ways to reach// n'th stair when a person// can climb either 1 or 2// stairs at a time // A recursive function// used by countWaysfunction countWaysUtil($n, $m){    if ($n <= 1)        return $n;    $res = 0;    for ($i = 1; $i <= $m &&                 $i <= $n; $i++)        $res += countWaysUtil($n - $i, $m);    return $res;} // Returns number of ways// to reach s'th stairfunction countWays($s, $m){    return countWaysUtil($s + 1, $m);} // Driver Code$s = 4; $m = 2;echo "Number of ways = ",      countWays($s, $m);     // This code is contributed// by akt_mit?>
<script>// A Javascript program to count// number of ways to reach// n'th stair when a person// can climb either 1 or 2// stairs at a time // A recursive function// used by countWaysfunction countWaysUtil(n, m){    if (n <= 1)        return n;    let res = 0;    for (let i = 1; i <= m &&                 i <= n; i++)        res += countWaysUtil(n - i, m);    return res;} // Returns number of ways// to reach s'th stairfunction countWays(s, m){    return countWaysUtil(s + 1, m);} // Driver Codelet s = 4;let m = 2;document.write("Number of ways = " + countWays(s, m));     // This code is contributed by _saurabh_jaiswal</script>
Number of ways = 5
Complexity Analysis: 
Time Complexity: O(2^n) The time complexity of the above implementation is exponential (golden ratio raised to power n) due to redundant calculations. It can be optimized to O(m*n) by using dynamic programming.
Auxiliary Space: O(1)
Method 2: Memoization
We can use the bottom-up approach of dp to solve this problem as well
For this, we can create an array dp[] and initialize it with -1.
Whenever we see that a subproblem is not solved we can call the recursive method, 
else we stop the recursion if that the subproblem is solved already.
C++
Java
Python3
Javascript
// C++ program to count number of// ways to reach Nth stair#include <bits/stdc++.h>using namespace std; // A simple recursive program to// find N'th fibonacci numberint fib(int n, int dp[]){    if (n <= 1)        return dp[n] = 1;       if(dp[n] != -1 ){        return dp[n] ;    }    dp[n] = fib(n - 1, dp) + fib(n - 2, dp);    return  dp[n] ;} // Returns number of ways to// reach s'th stairint countWays(int n){    int dp[n+1] ;    memset(dp, -1, sizeof dp) ;    fib(n, dp) ;    return dp[n] ;} // Driver Cint main(){    int n = 4;     cout << "Number of ways = " << countWays(n);     return 0;}
// Java program to count number of// ways to reach Nth stairclass GFG{   // A simple recursive program to  // find N'th fibonacci number  static int fib(int n, int dp[])  {    if (n <= 1)      return dp[n] = 1;     if (dp[n] != -1) {      return dp[n];    }    dp[n] = fib(n - 1, dp) + fib(n - 2, dp);    return dp[n];  }   // Returns number of ways to  // reach s'th stair  static int countWays(int n)  {    int[] dp = new int[n + 1];    for (int i = 0; i < n + 1; i++) {      dp[i] = -1;    }    fib(n, dp);    return dp[n];  }   // Driver code  public static void main(String[] args)  {    int n = 4;    System.out.println(countWays(n));  }} // This code is contributed by Karandeep1234
# Python program to count number of# ways to reach Nth stair # A simple recursive program to# find N'th fibonacci numberdef fib(n, dp):     if (n <= 1):        return 1       if(dp[n] != -1 ):        return dp[n]     dp[n] = fib(n - 1, dp) + fib(n - 2, dp)    return  dp[n] # Returns number of ways to# reach s'th stairdef countWays(n):     dp = [-1 for i in range(n + 1)]    fib(n, dp)    return dp[n] # Driver Coden = 4 print("Number of ways = " + str(countWays(n))) # This code is contributed by shinjanpatra
<script> // JavaScript program to count number of// ways to reach Nth stair  // A simple recursive program to// find N'th fibonacci numberfunction fib(n, dp){    if (n <= 1)        return dp[n] = 1;       if(dp[n] != -1 ){        return dp[n] ;    }    dp[n] = fib(n - 1, dp) + fib(n - 2, dp);    return  dp[n] ;} // Returns number of ways to// reach s'th stairfunction countWays(n){    let dp = new Array(n+1).fill(-1) ;    fib(n, dp) ;    return dp[n] ;} // Driver Code let n = 4; document.write("Number of ways = " + countWays(n)); // This code is contributed by shinjanpatra.</script>
Number of ways = 5
Complexity Analysis:
Time Complexity: O(n)
Auxiliary Space: O(n)
Method 3: This method uses the technique of Dynamic Programming to arrive at the solution.
Approach: We create a table res[] in bottom up manner using the following relation: 
res[i] = res[i] + res[i-j] for every (i-j) >= 0
such that the ith index of the array will contain the number of ways required to reach the ith step considering all the possibilities of climbing (i.e. from 1 to i).
Below code implements the above approach: 
C++
C
Java
Python
C#
PHP
Javascript
// C++ program to count number of ways// to reach n'th stair when a person// can climb 1, 2, ..m stairs at a time#include <iostream>using namespace std; // A recursive function used by countWaysint countWaysUtil(int n, int m){    int res[n];    res[0] = 1;    res[1] = 1;         for(int i = 2; i < n; i++)    {       res[i] = 0;               for(int j = 1; j <= m && j <= i; j++)          res[i] += res[i - j];    }    return res[n - 1];} // Returns number of ways to reach s'th stairint countWays(int s, int m){    return countWaysUtil(s + 1, m);} // Driver codeint main(){    int s = 4, m = 2;         cout << "Number of ways = "         << countWays(s, m);              return 0;} // This code is contributed by shubhamsingh10
// A C program to count number of ways// to reach n'th stair when// a person can climb 1, 2, ..m stairs at a time#include <stdio.h> // A recursive function used by countWaysint countWaysUtil(int n, int m){    int res[n];    res[0] = 1;    res[1] = 1;    for (int i = 2; i < n; i++) {        res[i] = 0;        for (int j = 1; j <= m && j <= i; j++)            res[i] += res[i - j];    }    return res[n - 1];} // Returns number of ways to reach s'th stairint countWays(int s, int m){    return countWaysUtil(s + 1, m);} // Driver program to test above functionsint main(){    int s = 4, m = 2;    printf("Number of ways = %d", countWays(s, m));    return 0;}
// Java program to count number of ways// to reach n't stair when a person// can climb 1, 2, ..m stairs at a time class GFG {    // A recursive function used by countWays    static int countWaysUtil(int n, int m)    {        int res[] = new int[n];        res[0] = 1;        res[1] = 1;        for (int i = 2; i < n; i++) {            res[i] = 0;            for (int j = 1; j <= m && j <= i; j++)                res[i] += res[i - j];        }        return res[n - 1];    }     // Returns number of ways to reach s'th stair    static int countWays(int s, int m)    {        return countWaysUtil(s + 1, m);    }     // Driver method    public static void main(String[] args)    {        int s = 4, m = 2;        System.out.println("Number of ways = "                           + countWays(s, m));    }}
# A program to count the number of# ways to reach n'th stair # Recursive function used by countWaysdef countWaysUtil(n, m):    # Creates list res with all elements 0    res = [0 for x in range(n)]    res[0], res[1] = 1, 1         for i in range(2, n):        j = 1        while j<= m and j<= i:            res[i] = res[i] + res[i-j]            j = j + 1    return res[n-1] # Returns number of ways to reach s'th stairdef countWays(s, m):    return countWaysUtil(s + 1, m)     # Driver Programs, m = 4, 2print "Number of ways =", countWays(s, m)     # Contributed by Harshit Agrawal
// C# program to count number// of ways to reach n'th stair when// a person can climb 1, 2, ..m// stairs at a timeusing System;class GFG {     // A recursive function    // used by countWays    static int countWaysUtil(int n, int m)    {        int[] res = new int[n];        res[0] = 1;        res[1] = 1;        for (int i = 2; i < n; i++) {            res[i] = 0;            for (int j = 1; j <= m && j <= i; j++)                res[i] += res[i - j];        }        return res[n - 1];    }     // Returns number of ways    // to reach s'th stair    static int countWays(int s, int m)    {        return countWaysUtil(s + 1, m);    }     // Driver Code    public static void Main()    {        int s = 4, m = 2;        Console.WriteLine("Number of ways = "                          + countWays(s, m));    }} // This code is contributed by anuj_67.
<?php// A PHP program to count number// of ways to reach n't stair when// a person can climb 1, 2, ..m// stairs at a time // A recursive function used by countWaysfunction countWaysUtil($n, $m){    $res[0] = 1; $res[1] = 1;    for ($i = 2; $i < $n; $i++)    {        $res[$i] = 0;        for ($j = 1; $j <= $m && $j <= $i; $j++)        $res[$i] += $res[$i - $j];    }    return $res[$n - 1];} // Returns number of ways// to reach s'th stairfunction countWays($s, $m){    return countWaysUtil($s + 1, $m);}     // Driver Code    $s = 4;    $m = 2;    echo "Number of ways = ", countWays($s, $m); // This code is contributed by m_kit?>
<script> // A Javascript program to count number// of ways to reach n't stair when// a person can climb 1, 2, ..m// stairs at a time // A recursive function used by countWaysfunction countWaysUtil(n, m){    let res = [];    res[0] = 1;    res[1] = 1;    for (let i = 2; i < n; i++)    {        res[i] = 0;        for (let j = 1; j <= m && j <= i; j++)        res[i] += res[i - j];    }    return res[n - 1];} // Returns number of ways// to reach s'th stairfunction countWays(s, m){    return countWaysUtil(s + 1, m);}     // Driver Code    let s = 4;    let m = 2;    document.write("Number of ways = " + countWays(s, m)); // This code is contributed by _saurabh_jaiswal </script>
Number of ways = 5
Complexity Analysis: 
Time Complexity: O(m*n)
Auxiliary Space: O(n)
Method 4: The third method uses the technique of Sliding Window to arrive at the solution.Approach: This method efficiently implements the above Dynamic Programming approach. In this approach for the ith stair, we keep a window of sum of last m possible stairs from which we can climb to the ith stair. Instead of running an inner loop, we maintain the result of the inner loop in a temporary variable. We remove the elements of the previous window and add the element of the current window and update the sum.
Below code implements the above idea 
C++
C
Java
Python3
C#
Javascript
// A C++ program to count the number of ways// to reach n'th stair when user// climb 1 .. m stairs at a time.// Contributor: rsampaths16#include <iostream>using namespace std; // Returns number of ways// to reach s'th stairint countWays(int n, int m){    int res[n + 1];    int temp = 0;    res[0] = 1;    for (int i = 1; i <= n; i++)    {        int s = i - m - 1;        int e = i - 1;        if (s >= 0)        {            temp -= res[s];        }        temp += res[e];        res[i] = temp;    }    return res[n];} // Driver Codeint main(){    int n = 5, m = 3;    cout << "Number of ways = "         << countWays(n, m);    return 0;} // This code is contributed by shubhamsingh10
// A C program to count the number of ways// to reach n'th stair when user// climb 1 .. m stairs at a time.// Contributor: rsampaths16#include <stdio.h> // Returns number of ways// to reach s'th stairint countWays(int n, int m){    int res[n + 1];    int temp = 0;    res[0] = 1;    for (int i = 1; i <= n; i++) {        int s = i - m - 1;        int e = i - 1;        if (s >= 0) {            temp -= res[s];        }        temp += res[e];        res[i] = temp;    }    return res[n];} // Driver Codeint main(){    int n = 5, m = 3;    printf("Number of ways = %d",           countWays(n, m));    return 0;}
// Java program to count number of// ways to reach n't stair when a// person can climb 1, 2, ..m// stairs at a timeclass GFG{     // Returns number of ways// to reach s'th stairstatic int countWays(int n, int m){    int res[] = new int[n + 1];    int temp = 0;    res[0] = 1;         for(int i = 1; i <= n; i++)    {       int s = i - m - 1;       int e = i - 1;       if (s >= 0)       {           temp -= res[s];       }       temp += res[e];       res[i] = temp;    }    return res[n];}     // Driver Codepublic static void main(String[] args){    int n = 5, m = 3;    System.out.println("Number of ways = " +                       countWays(n, m));}} // This code is contributed by equbalzeeshan
# Python3 program to count the number# of ways to reach n'th stair when# user climb 1 .. m stairs at a time. # Function to count number of ways# to reach s'th stairdef countWays(n, m):         temp = 0    res = [1]         for i in range(1, n + 1):        s = i - m - 1        e = i - 1        if (s >= 0):            temp -= res[s]        temp += res[e]        res.append(temp)             return res[n] # Driver Coden = 5m = 3 print('Number of ways =', countWays(n, m)) # This code is contributed by 31ajaydandge
// C# program to count number of// ways to reach n'th stair when// a person can climb 1, 2, ..m// stairs at a timeusing System;class GFG{     // Returns number of ways// to reach s'th stairstatic int countWays(int n, int m){    int[] res = new int[n + 1];    int temp = 0;    res[0] = 1;         for(int i = 1; i <= n; i++)    {       int s = i - m - 1;       int e = i - 1;       if (s >= 0)       {           temp -= res[s];       }       temp += res[e];       res[i] = temp;    }    return res[n];} // Driver Codepublic static void Main(){    int n = 5, m = 3;    Console.WriteLine("Number of ways = " +                      countWays(n, m));}} // This code is contributed by equbalzeeshan
<script> // Javascript program to count number of// ways to reach n't stair when a// person can climb 1, 2, ..m// stairs at a time    // Returns number of ways// to reach s'th stair    function countWays(n , m)    {        var res = Array(n + 1).fill(0);        var temp = 0;        res[0] = 1;         for (i = 1; i <= n; i++) {            var s = i - m - 1;            var e = i - 1;            if (s >= 0) {                temp -= res[s];            }            temp += res[e];            res[i] = temp;        }        return res[n];    }     // Driver Code             var n = 5, m = 3;        document.write("Number of ways = " +        countWays(n, m)); // This code contributed by Rajput-Ji </script>
Number of ways = 13
Complexity Analysis:  
Time Complexity: O(n)
Auxiliary Space: O(n)
This article is contributed by Abhishek. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above
Method 5: The fourth method uses simple mathematics but this is only applicable for this problem if (Order does not matter) while counting steps.
Approach: In This method we simply count the number of sets having 2.
C++
Java
Python3
C#
Javascript
#include <iostream>using namespace std; int main() {    int n;    n=5;     // Here n/2 is done to count the number 2's in n    // 1 is added for case where there is no 2.    // eg: if n=4 ans will be 3.    // {1,1,1,1} set having no 2.    // {1,1,2} ans {2,2} (n/2) sets containing 2.     cout<<"Number of ways when order of steps does not matter is : "<<1+(n/2)<<endl;          return 0;}
import java.util.*; class GFG{ public static void main(String[] args){    int n;    n = 5;         // Here n/2 is done to count the number 2's    // in n 1 is added for case where there is no 2.    // eg: if n=4 ans will be 3.    // {1,1,1,1} set having no 2.    // {1,1,2} ans {2,2} (n/2) sets containing 2.    System.out.print("Number of ways when order of steps " +                     "does not matter is : " + (1 + (n / 2)));}} // This code is contributed by todaysgaurav
n = 5 # Here n/2 is done to count the number 2's in n# 1 is added for case where there is no 2.# eg: if n=4 ans will be 3.# {1,1,1,1} set having no 2.# {1,1,2} ans {2,2} (n/2) sets containing 2.print("Number of ways when order "      "of steps does not matter is : ", 1 + (n // 2))  # This code is contributed by rohitsingh07052
using System; class GFG{static public void Main(){    int n;    n = 5;         // Here n/2 is done to count the number 2's    // in n 1 is added for case where there is no 2.    // eg: if n=4 ans will be 3.    // {1,1,1,1} set having no 2.    // {1,1,2} ans {2,2} (n/2) sets containing 2.    Console.WriteLine("Number of ways when order of steps " +                      "does not matter is : " + (1 + (n / 2))); }} // This code is contributed by Ankita saini
<script> var n;n = 5; // Here n/2 is done to count the number 2's in n// 1 is added for case where there is no 2.// eg: if n=4 ans will be 3.// {1,1,1,1} set having no 2.// {1,1,2} ans {2,2} (n/2) sets containing 2.document.write("Number of ways when order " +               "of steps does not matter is : ",               parseInt(1 + (n / 2)));    // This code is contributed by Ankita saini </script>
Number of ways when order of steps does not matter is : 3
Complexity Analysis:
Time Complexity : O(1)
Space Complexity : O(1)
Note: This Method is only applicable for the question Count ways to N’th Stair(Order does not matter) .
Order does not matter means for n = 4  {1 2 1}  ,{2 1 1}  , {1 1 2} are considered same.
Method 6: This method uses the technique of Matrix Exponentiation to arrive at the solution.
Approach: The number of ways to reach nth stair (Order matters) is equal to the sum of number of ways to reach (n-1)th stair and (n-2)th stair
This corresponds to the following recurrence relation:
f(n) = f(n-1) + f(n-2)

f(1) = 1
f(2) = 2
where f(n) indicates the number of ways to reach nth stair
Note: 
f(1) = 1 because there is only 1 way to reach n=1 stair  {1}
f(2) = 2 because there are 2 ways to reach n=2 stairs  {1,1} , {2}
It is a type of linear recurrence relation with constant coefficients and we can solve them using Matrix Exponentiation method which basically finds a transformation matrix for a given recurrence relation and repeatedly applies this transformation to a base vector to arrive at the solution).
F(n) = CN-1F(1)
where
C is the transformation matrix
F(1) is the base vector
F(n) is the desired solution
So, for our case the transformation matrix C would be:
CN-1 can be calculated using Divide and Conquer technique, in O( (K^3) Log n) where K is dimension of C 
And F(1):
As an example, For n= 4: 
F(4) = C3F(1)
C3 = 
Hence, C3F(1) = 
C++
Java
Python3
C#
Javascript
#include <bits/stdc++.h>using namespace std;typedef vector<vector<long long> > matrix; #define LOOP(i, n) for (int i = 1; i < n; i++) // Computes A*B// where A,B are square matricesmatrix mul(matrix A, matrix B, long long MOD = 1000000007){    int K = A.size();    matrix C(K, vector<long long>(K, 0));    LOOP(i, K)        LOOP(j, K)            LOOP(k, K)                C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % MOD;    return C;} // Computes A^nmatrix power(matrix A, long long n){    if (n == 1)        return A;    if (n % 2 != 0) {        // n is odd        // A^n = A * [ A^(n-1) ]        A = mul(A, power(A, n - 1));    }    else {        // n is even        // A^n = [ A^(n/2) ] * [ A^(n/2) ]        A = power(A, n / 2);        A = mul(A, A);    }    return A;} long long ways(int n){    vector<long long> F(3);    F[1] = 1;    F[2] = 2;    int K = 2;    long long MOD = 1000000007;    // create K*K matrix    matrix C(K + 1, vector<long long>(K + 1, 0));    /*      A matrix with (i+1)th element as 1 and last row      contains constants      [          [0 1 0 0 ... 0]          [0 0 1 0 ... 0]          [0 0 0 1 ... 0]          [. . . . ... .]          [. . . . ... .]          [c(k) c(k-1) c(k-2) ... c1]      ]    */    for (int i = 1; i < K; ++i) {        C[i][i + 1] = 1;    }    // Last row is the constants c(k) c(k-1) ... c1    // f(n) = 1*f(n-1) + 1*f(n-2)    C[K][1] = 1;    C[K][2] = 1;     if (n <= 2)        return F[n];     // f(n) = C^(n-1)*F    C = power(C, n - 1);     long long result = 0;     // result will be the first row of C^(n-1)*F    for (int i = 1; i <= K; ++i) {        result = (result + C[1][i] * F[i]) % MOD;    }    return result;} int main(){    int n = 4;    cout << "Number of ways = " << ways(n) << endl;} // This code is contributed by darshang631
import java.util.*; class GFG{       // Computes A*B    // where A,B are square matrices    static long[][] mul(long[][] A, long[][] B, long MOD) {        int K = A.length;        long[][] C = new long[K][K];        for (int i = 1; i < K; i++)            for (int j = 1; j < K; j++)                for (int k = 1; k < K; k++)                    C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % MOD;        return C;    }     // Computes A^n    static long[][] power(long[][] A, long n) {        if (n == 1)            return A;        if (n % 2 != 0)        {                       // n is odd            // A^n = A * [ A^(n-1) ]            A = mul(A, power(A, n - 1), 1000000007);        }      else      {            // n is even            // A^n = [ A^(n/2) ] * [ A^(n/2) ]            A = power(A, n / 2);            A = mul(A, A, 1000000007);        }        return A;    }     static long ways(int n) {        long[] F = new long[3];        F[1] = 1;        F[2] = 2;        int K = 2;        long MOD = 1000000007;               // create K*K matrix        long[][] C = new long[K + 1][K + 1];        /*         * A matrix with (i+1)th element as 1 and last row contains constants [ [0 1 0 0         * ... 0] [0 0 1 0 ... 0] [0 0 0 1 ... 0] [. . . . ... .] [. . . . ... .] [c(k)         * c(k-1) c(k-2) ... c1] ]         */        for (int i = 1; i < K; ++i) {            C[i][i + 1] = 1;        }        // Last row is the constants c(k) c(k-1) ... c1        // f(n) = 1*f(n-1) + 1*f(n-2)        C[K][1] = 1;        C[K][2] = 1;         if (n <= 2)            return F[n];         // f(n) = C^(n-1)*F        C = power(C, n - 1);         long result = 0;         // result will be the first row of C^(n-1)*F        for (int i = 1; i <= K; ++i) {            result = (result + C[1][i] * F[i]) % MOD;        }        return result;    }     public static void main(String[] args) {        int n = 4;        System.out.print("Number of ways = " + ways(n) + "\n");    }} // This code is contributed by umadevi9616
# Computes A*B# where A,B are square matricesdef mul(A, B, MOD):    K = len(A);    C = [[0 for i in range(K)] for j in range(K)] ;    for i in range(1, K):        for j in range(1, K):            for k in range(1, K):                C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % MOD;    return C; # Computes A^ndef power( A,  n):    if (n == 1):        return A;    if (n % 2 != 0):         # n is odd        # A^n = A * [ A^(n-1) ]        A = mul(A, power(A, n - 1), 1000000007);    else:        # n is even        # A^n = [ A^(n/2) ] * [ A^(n/2) ]        A = power(A, n // 2);        A = mul(A, A, 1000000007);         return A; def ways(n):    F = [0 for i in range(3)];    F[1] = 1;    F[2] = 2;    K = 2;    MOD = 1000000007;     # create K*K matrix    C = [[0 for i in range(K+1)] for j in range(K+1)];    '''     * A matrix with (i+1)th element as 1 and last row contains constants [ [0 1 0 0     * ... 0] [0 0 1 0 ... 0] [0 0 0 1 ... 0] [. . . . ... .] [. . . . ... .] [c(k)     * c(k-1) c(k-2) ... c1] ]     '''    for i in range(1,K):        C[i][i + 1] = 1;         # Last row is the constants c(k) c(k-1) ... c1    # f(n) = 1*f(n-1) + 1*f(n-2)    C[K][1] = 1;    C[K][2] = 1;     if (n <= 2):        return F[n];     # f(n) = C^(n-1)*F    C = power(C, n - 1);    result = 0;     # result will be the first row of C^(n-1)*F    for i in range(1,K+1):        result = (result + C[1][i] * F[i]) % MOD;         return result; # Driver codeif __name__ == '__main__':    n = 4;    print("Number of ways = " , ways(n) , ""); # This code is contributed by gauravrajput1
using System; public class GFG {     // Computes A*B    // where A,B are square matrices    static long[,] mul(long[,] A, long[,] B, long MOD) {        int K = A.GetLength(0);        long[,] C = new long[K,K];        for (int i = 1; i < K; i++)            for (int j = 1; j < K; j++)                for (int k = 1; k < K; k++)                    C[i,j] = (C[i,j] + A[i,k] * B[k,j]) % MOD;        return C;    }     // Computes A^n    static long[,] power(long[,] A, long n) {        if (n == 1)            return A;        if (n % 2 != 0) {             // n is odd            // A^n = A * [ A^(n-1) ]            A = mul(A, power(A, n - 1), 1000000007);        } else {            // n is even            // A^n = [ A^(n/2) ] * [ A^(n/2) ]            A = power(A, n / 2);            A = mul(A, A, 1000000007);        }        return A;    }     static long ways(int n) {        long[] F = new long[3];        F[1] = 1;        F[2] = 2;        int K = 2;        long MOD = 1000000007;         // create K*K matrix        long[,] C = new long[K + 1,K + 1];        /*         * A matrix with (i+1)th element as 1 and last row contains constants [ [0 1 0 0         * ... 0] [0 0 1 0 ... 0] [0 0 0 1 ... 0] [. . . . ... .] [. . . . ... .] [c(k)         * c(k-1) c(k-2) ... c1] ]         */        for (int i = 1; i < K; ++i) {            C[i,i + 1] = 1;        }        // Last row is the constants c(k) c(k-1) ... c1        // f(n) = 1*f(n-1) + 1*f(n-2)        C[K,1] = 1;        C[K,2] = 1;         if (n <= 2)            return F[n];         // f(n) = C^(n-1)*F        C = power(C, n - 1);         long result = 0;         // result will be the first row of C^(n-1)*F        for (int i = 1; i <= K; ++i) {            result = (result + C[1,i] * F[i]) % MOD;        }        return result;    }     public static void Main(String[] args) {        int n = 4;        Console.Write("Number of ways = " + ways(n) + "\n");    }} // This code is contributed by umadevi9616
<script>    // Computes A*B    // where A,B are square matrices     function mul( A,  B , MOD) {        var K = A.length;        var C = Array(K).fill().map(()=>Array(K).fill(0));        for (var i = 1; i < K; i++)            for (var j = 1; j < K; j++)                for (var k = 1; k < K; k++)                    C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % MOD;        return C;    }     // Computes A^n     function power( A , n) {        if (n == 1)            return A;        if (n % 2 != 0) {             // n is odd            // A^n = A * [ A^(n-1) ]            A = mul(A, power(A, n - 1), 1000000007);        } else {            // n is even            // A^n = [ A^(n/2) ] * [ A^(n/2) ]            A = power(A, n / 2);            A = mul(A, A, 1000000007);        }        return A;    }     function ways(n) {        var F = Array(3).fill(0);        F[1] = 1;        F[2] = 2;        var K = 2;        var MOD = 1000000007;         // create K*K matrix    var  C = Array(K+1).fill().map(()=>Array(K+1).fill(0));        /*         * A matrix with (i+1)th element as 1 and last row contains constants [ [0 1 0 0         * ... 0] [0 0 1 0 ... 0] [0 0 0 1 ... 0] [. . . . ... .] [. . . . ... .] [c(k)         * c(k-1) c(k-2) ... c1] ]         */        for (var i = 1; i < K; ++i) {            C[i][i + 1] = 1;        }        // Last row is the constants c(k) c(k-1) ... c1        // f(n) = 1*f(n-1) + 1*f(n-2)        C[K][1] = 1;        C[K][2] = 1;         if (n <= 2)            return F[n];         // f(n) = C^(n-1)*F        C = power(C, n - 1);         var result = 0;         // result will be the first row of C^(n-1)*F        for (var i = 1; i <= K; ++i) {            result = (result + C[1][i] * F[i]) % MOD;        }        return result;    }         var n = 4;        document.write("Number of ways = " + ways(n) + "\n"); // This code is contributed by umadevi9616</script>
Number of ways = 5
Complexity Analysis:
Time Complexity: O(Log n)
Space Complexity: O(1)
Generalization of the Problem:
Given an array A {a1, a2, ...., am} containing all valid steps, compute the number of ways to reach nth stair. (Order does matter)
Examples:
Input:
    A = [1,2] 
    n = 4  
Output: 5  
Explanation:
This is the given problem, i.e, count the number of ways to reach n=4 stairs with climbing 1 or 2 stairs at a time
Therefore, ways will be: {1,1,1,1} {1,1,2} {1,2,1} {2,1,1} {2,2} = 5


Input:
    A = [2,4,5]
    n = 9
Output: 5
Explanation:
There are 5 ways to reach n=9 stairs with climbing 2 or 4 or 5 stairs at a time
Therefore, ways will be: {5,4} {4,5} {2,2,5} {2,5,2} {5,2,2} = 5 
 Approach: 
The number of ways to reach nth stair is given by the following recurrence relation
 
Let K be the largest element in A.
Step1: Calculate base vector F(1) ( consisting of f(1) .... f(K)  )
It can be done in O(m2K)  time using dynamic programming approach as follows:
Let’s take A = {2,4,5} as an example. To calculate F(1) = { f(1), f(2), f(3), f(4), f(5)  } we will maintain an initially empty array and iteratively append Ai to it and for each Ai we will find the number of ways to reach [Ai-1, to Ai,] 
Hence for A = {2 ,4 ,5}
Let T be the initially empty array
Iteration 1: T = {2}        n = {1,2}        dp = {0,1}         (Number of ways to reach n=1,2 with steps given by T) 
Iteration 2: T = {2,4}        n = {1,2,3,4}    dp = {0,1,0,2}     (Number of ways to reach n=1,2,3,4 with steps given by T)
Iteration 3: T = {2,4,5}    n = {1,2,3,4,5}    dp = {0,1,0,2,1} (Number of ways to reach n=1,2,3,4,5 with steps given by T)
Note: Since some values are already calculated (1,2 for Iteration 2, etc.) we can avoid them in loop
After all iterations, the dp array would be: [0,1,0,2,1] 
Thus, base vector F(1) for A = [2,4,5] is: 
Now that we have the base vector F(1), calculation of C (Transformation matrix) is easy
Step 2: Calculate C, the transformation matrix
It is a matrix having elements Ai,i+1= 1 and last row contains constants
Now constants can be determined by the presence of that element in A
So for A = [2,4,5] constants will be c = [1,1,0,1,0]   (Ci = 1 if (K-i+1) is present in A, or else 0  where 1 <= i <= K )
Thus, Transformation matrix C for A =[2,4,5] is:
Step 3: Calculate F(n)
To calculate F(n), following formula is used:
F(n) = Cn-1F(1)
Now that we have C and F(1) we can use Divide and Conquer technique to find Cn-1 and hence the desired output
C++
Java
Python3
C#
Javascript
#include <bits/stdc++.h>using namespace std;typedef vector<vector<long long> > matrix; #define LOOP(i, n) for (int i = 1; i < n; i++) // Computes A*B when A,B are square matrices of equal// dimensions)matrix mul(matrix A, matrix B, long long MOD = 1000000007){    int K = A.size();    matrix C(K, vector<long long>(K, 0));    LOOP(i, K)        LOOP(j, K)            LOOP(k, K)                C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % MOD;    return C;} matrix power(matrix A, long long n){    if (n == 1)        return A;    if (n % 2 != 0) {        // n is odd        // A^n = A * [ A^(n-1) ]        A = mul(A, power(A, n - 1));    }    else {        // n is even        // A^n = [ A^(n/2) ] * [ A^(n/2) ]        A = power(A, n / 2);        A = mul(A, A);    }    return A;} vector<long long> initialize(vector<long long> A){    // Initializes the base vector F(1)       int K = A[A.size() - 1]; // Assuming A is sorted    vector<long long> F(K + 1, 0);    vector<long long> dp(K + 1);    dp[0] = 0;    dp[A[1]] = 1; // There is one and only one way to reach                  // first element    F[A[1]] = 1;    for (int i = 2; i < A.size(); ++i) {        // Loop through A[i-1] to A[i] and fill the dp array        for (int j = A[i - 1] + 1; j <= A[i]; ++j) {                       // dp[j] = dp[j-A[0]] + .. + dp[j-A[i-1]]            for (int k = 1; k < i; ++k) {                dp[j] += dp[j - A[k]];            }        }        // There will be one more way to reach A[i]        dp[A[i]] += 1;        F[A[i]] = dp[A[i]];    }    return F;}long long ways(vector<long long> A, int n){    int K = A[A.size() - 1]; // Assuming A is sorted    vector<long long> F = initialize(A); // O(m^2*K)    int MOD = 1000000007;    // create K*K matrix    matrix C(K + 1, vector<long long>(K + 1, 0));    /*    A matrix with (i+1)th element as 1 and last row contains    constants    [        [0 1 0 0 ... 0]        [0 0 1 0 ... 0]        [0 0 0 1 ... 0]        [. . . . ... .]        [. . . . ... .]        [c(k) c(k-1) c(k-2) ... c1]    ]    */    for (int i = 1; i < K; ++i) {        C[i][i + 1] = 1;    }    // Last row is the constants c(k) c(k-1) ... c1    // f(n) = 1*f(n-1) + 1*f(n-2)    for (int i = 1; i < A.size(); ++i) {        C[K][K - A[i] + 1] = 1;    }     if (n <= K)        return F[n];    // F(n) = C^(n-1)*F    C = power(C, n - 1); // O(k^3Log(n))     long long result = 0;     // result will be the first row of C^(n-1)*F    for (int i = 1; i <= K; ++i) {        result = (result + C[1][i] * F[i]) % MOD;    }    return result;} int main(){    int n = 9;    vector<long long> A = {        0, 2, 4, 5    }; // 0 is just because we are using 1 based indexing    cout << "Number of ways = " << ways(A, n) << endl;} // This code is contributed by darshang631
import java.util.*; class GFG{   // Computes A*B when A,B are square matrices of equal  // dimensions)  static int[][] mul(int[][] A, int[][] B,int MOD)  {    int K = A.length;    int[][] C = new int[K][K];    for (int i = 1; i < K; i++)      for (int j = 1; j < K; j++)        for (int k = 1; k < K; k++)          C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % MOD;    return C;  }   static int[][] power(int[][] A, long n)  {    if (n == 1)      return A;    if (n % 2 != 0)    {       // n is odd      // A^n = A * [ A^(n-1) ]      A = mul(A, power(A, n - 1), 1000000007);    }    else {      // n is even      // A^n = [ A^(n/2) ] * [ A^(n/2) ]      A = power(A, n / 2);      A = mul(A, A, 1000000007);    }    return A;  }   static int[] initialize(int[] A)  {    // Initializes the base vector F(1)     int K = A[A.length - 1]; // Assuming A is sorted    int[] F = new int[K+1];    int[] dp = new int[K+1];    dp[0] = 0;    dp[A[1]] = 1; // There is one and only one way to reach    // first element    F[A[1]] = 1;    for (int i = 2; i < A.length; ++i)    {       // Loop through A[i-1] to A[i] and fill the dp array      for (int j = A[i - 1] + 1; j <= A[i]; ++j) {         // dp[j] = dp[j-A[0]] + .. + dp[j-A[i-1]]        for (int k = 1; k < i; ++k) {          dp[j] += dp[j - A[k]];        }      }       // There will be one more way to reach A[i]      dp[A[i]] += 1;      F[A[i]] = dp[A[i]];    }    return F;  }  static int ways(int[] A, int n)  {    int K = A[A.length - 1]; // Assuming A is sorted    int[] F = initialize(A); // O(m^2*K)    int MOD = 1000000007;     // create K*K matrix    int[][] C = new int[K + 1][K + 1];     /*    A matrix with (i+1)th element as 1 and last row contains    constants    [        [0 1 0 0 ... 0]        [0 0 1 0 ... 0]        [0 0 0 1 ... 0]        [. . . . ... .]        [. . . . ... .]        [c(k) c(k-1) c(k-2) ... c1]    ]    */    for (int i = 1; i < K; ++i) {      C[i][i + 1] = 1;    }     // Last row is the constants c(k) c(k-1) ... c1    // f(n) = 1*f(n-1) + 1*f(n-2)    for (int i = 1; i < A.length; ++i) {      C[K][K - A[i] + 1] = 1;    }     if (n <= K)      return F[n];    // F(n) = C^(n-1)*F    C = power(C, n - 1); // O(k^3Log(n))     int result = 0;     // result will be the first row of C^(n-1)*F    for (int i = 1; i <= K; ++i) {      result = (result + C[1][i] * F[i]) % MOD;    }    return result;  }   public static void main(String[] args)  {    int n = 9;    int[] A = {0, 2, 4, 5};     // 0 is just because we are using 1 based indexing    System.out.print("Number of ways = " +  ways(A, n) +"\n");  }} // This code is contributed by umadevi9616
# Computes A*B when A,B are square matrices of equal# dimensions)def mul(A, B, MOD):    K = len(A);    C = [[0 for i in range(K)] for j in range(K)] ;    for i in range(1, K):        for j in range(1, K):            for k in range(1, K):                C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % MOD;    return C; def power(A, n):    if (n == 1):        return A;    if (n % 2 != 0):         # n is odd        # A^n = A * [ A^(n-1) ]        A = mul(A, power(A, n - 1), 1000000007);    else:        # n is even        # A^n = [ A^(n/2) ] * [ A^(n/2) ]        A = power(A, n // 2);        A = mul(A, A, 1000000007);         return A; def initialize(A):    # Initializes the base vector F(1)     K = A[len(A)-1]; # Assuming A is sorted    F = [0 for i in range(K+1)];    dp = [0 for i in range(K+1)];    dp[0] = 0;    dp[A[1]] = 1; # There is one and only one way to reach    # first element    F[A[1]] = 1;    for i in range(2,len(A)):         # Loop through A[i-1] to A[i] and fill the dp array        for j in range(A[i - 1] + 1,A[i]+1):             # dp[j] = dp[j-A[0]] + .. + dp[j-A[i-1]]            for k in range(1,i):                dp[j] += dp[j - A[k]];                     # There will be one more way to reach A[i]        dp[A[i]] += 1;        F[A[i]] = dp[A[i]];         return F; def ways(A, n):    K = A[len(A) - 1]; # Assuming A is sorted    F = initialize(A); # O(m^2*K)    MOD = 1000000007;     # create K*K matrix    C = [[0 for i in range(K+1)] for j in range(K+1)];     '''     * A matrix with (i+1)th element as 1 and last row contains constants [ [0 1 0 0     * ... 0] [0 0 1 0 ... 0] [0 0 0 1 ... 0] [. . . . ... .] [. . . . ... .] [c(k)     * c(k-1) c(k-2) ... c1] ]     '''    for i in range(1,K):        C[i][i + 1] = 1;          # Last row is the constants c(k) c(k-1) ... c1    # f(n) = 1*f(n-1) + 1*f(n-2)    for i in range(1, len(A)):        C[K][K - A[i] + 1] = 1;         if (n <= K):        return F[n];    # F(n) = C^(n-1)*F    C = power(C, n - 1); # O(k^3Log(n))     result = 0;     # result will be the first row of C^(n-1)*F    for i in range(1, K+1):        result = (result + C[1][i] * F[i]) % MOD;         return result; # Driver codeif __name__ == '__main__':    n = 9;    A = [ 0, 2, 4, 5] ;     # 0 is just because we are using 1 based indexing    print("Number of ways = " ,ways(A, n)); # This code is contributed by gauravrajput1
using System; public class GFG {     // Computes A*B when A,B are square matrices of equal    // dimensions)    static int[,] mul(int[,] A, int[,] B, int MOD) {        int K = A.GetLength(0);        int[,] C = new int[K,K];        for (int i = 1; i < K; i++)            for (int j = 1; j < K; j++)                for (int k = 1; k < K; k++)                    C[i,j] = (C[i,j] + A[i,k] * B[k,j]) % MOD;        return C;    }     static int[,] power(int[,] A, long n) {        if (n == 1)            return A;        if (n % 2 != 0) {             // n is odd            // A^n = A * [ A^(n-1) ]            A = mul(A, power(A, n - 1), 1000000007);        } else {            // n is even            // A^n = [ A^(n/2) ] * [ A^(n/2) ]            A = power(A, n / 2);            A = mul(A, A, 1000000007);        }        return A;    }     static int[] initialize(int[] A) {        // Initializes the base vector F(1)         int K = A[A.Length - 1]; // Assuming A is sorted        int[] F = new int[K + 1];        int[] dp = new int[K + 1];        dp[0] = 0;        dp[A[1]] = 1; // There is one and only one way to reach        // first element        F[A[1]] = 1;        for (int i = 2; i < A.Length; ++i) {             // Loop through A[i-1] to A[i] and fill the dp array            for (int j = A[i - 1] + 1; j <= A[i]; ++j) {                 // dp[j] = dp[j-A[0]] + .. + dp[j-A[i-1]]                for (int k = 1; k < i; ++k) {                    dp[j] += dp[j - A[k]];                }            }             // There will be one more way to reach A[i]            dp[A[i]] += 1;            F[A[i]] = dp[A[i]];        }        return F;    }     static int ways(int[] A, int n) {        int K = A[A.Length - 1]; // Assuming A is sorted        int[] F = initialize(A); // O(m^2*K)        int MOD = 1000000007;         // create K*K matrix        int[,] C = new int[K + 1,K + 1];         /*         * A matrix with (i+1)th element as 1 and last row contains constants [ [0 1 0 0         * ... 0] [0 0 1 0 ... 0] [0 0 0 1 ... 0] [. . . . ... .] [. . . . ... .] [c(k)         * c(k-1) c(k-2) ... c1] ]         */        for (int i = 1; i < K; ++i) {            C[i,i + 1] = 1;        }         // Last row is the constants c(k) c(k-1) ... c1        // f(n) = 1*f(n-1) + 1*f(n-2)        for (int i = 1; i < A.GetLength(0); ++i) {            C[K,K - A[i] + 1] = 1;        }         if (n <= K)            return F[n];        // F(n) = C^(n-1)*F        C = power(C, n - 1); // O(k^3Log(n))         int result = 0;         // result will be the first row of C^(n-1)*F        for (int i = 1; i <= K; ++i) {            result = (result + C[1,i] * F[i]) % MOD;        }        return result;    }     public static void Main(String[] args) {        int n = 9;        int[] A = { 0, 2, 4, 5 };         // 0 is just because we are using 1 based indexing        Console.Write("Number of ways = " + ways(A, n) + "\n");    }} // This code is contributed by gauravrajput1
<script>    // Computes A*B when A,B are square matrices of equal    // dimensions)     function mul(A,  B , MOD) {        var K = A.length;        var  C = Array(K).fill().map(()=>Array(K).fill(0));        for (var i = 1; i < K; i++)            for (var j = 1; j < K; j++)                for (var k = 1; k < K; k++)                    C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % MOD;        return C;    }      function power(A , n) {        if (n == 1)            return A;        if (n % 2 != 0) {             // n is odd            // A^n = A * [ A^(n-1) ]            A = mul(A, power(A, n - 1), 1000000007);        } else {            // n is even            // A^n = [ A^(n/2) ] * [ A^(n/2) ]            A = power(A, parseInt(n / 2));            A = mul(A, A, 1000000007);        }        return A;    }      function initialize(A) {        // Initializes the base vector F(1)         var K = A[A.length - 1]; // Assuming A is sorted        var F = Array(K+1).fill(0);        var dp = Array(K+1).fill(0);        dp[0] = 0;        dp[A[1]] = 1; // There is one and only one way to reach        // first element        F[A[1]] = 1;        for (var i = 2; i < A.length; ++i) {             // Loop through A[i-1] to A[i] and fill the dp array            for (var j = A[i - 1] + 1; j <= A[i]; ++j) {                 // dp[j] = dp[j-A[0]] + .. + dp[j-A[i-1]]                for (var k = 1; k < i; ++k) {                    dp[j] += dp[j - A[k]];                }            }             // There will be one more way to reach A[i]            dp[A[i]] += 1;            F[A[i]] = dp[A[i]];        }        return F;    }     function ways(A , n) {        var K = A[A.length - 1]; // Assuming A is sorted        var F = initialize(A); // O(m^2*K)        var MOD = 1000000007;         // create K*K matrix        var C = Array(K+1).fill().map(()=>Array(K+1).fill(0));         /*         * A matrix with (i+1)th element as 1 and last row contains constants [ [0 1 0 0         * ... 0] [0 0 1 0 ... 0] [0 0 0 1 ... 0] [. . . . ... .] [. . . . ... .] [c(k)         * c(k-1) c(k-2) ... c1] ]         */        for (var i = 1; i < K; ++i) {            C[i][i + 1] = 1;        }         // Last row is the constants c(k) c(k-1) ... c1        // f(n) = 1*f(n-1) + 1*f(n-2)        for (var i = 1; i < A.length; ++i) {            C[K][K - A[i] + 1] = 1;        }         if (n <= K)            return F[n];        // F(n) = C^(n-1)*F        C = power(C, n - 1); // O(k^3Log(n))         var result = 0;         // result will be the first row of C^(n-1)*F        for (var i = 1; i <= K; ++i) {            result = (result + C[1][i] * F[i]) % MOD;        }        return result;    }              var n = 9;        var A = [ 0, 2, 4, 5 ];         // 0 is just because we are using 1 based indexing        document.write("Number of ways = " + ways(A, n) + "\n"); // This code is contributed by gauravrajput1</script>
Number of ways = 5
Complexity Analysis:
Time Complexity: O( m2K + K3Logn )
            where
                m is the size of Array A
                K is the largest element in A
                n denotes the stair number (nth stair)
Space Complexity: O(K2)
Note: 
This approach is ideal when n is too large for iteration 
For Example: Consider this approach when (1 ≤ n ≤ 109) and (1 ≤ m,k ≤ 102)
jit_t
vt_m
nitin mittal
Saurabh Vemuri
Sampath Sukesh Ravolaparthi
bidibaaz123
SHUBHAMSINGH10
31ajaydandge
equbalzeeshan
kalambep51
_saurabh_jaiswal
blalverma92
rohitsingh07052
ankita_saini
Rajput-Ji
todaysgaurav
varshagumber28
darshang631
umadevi9616
GauravRajput1
prasanna1995
shinjanpatra
karandeep1234
Accolite
Amazon
Intel
Linkedin
Morgan Stanley
Samsung
sliding-window
Snapdeal
Dynamic Programming
Mathematical
Morgan Stanley
Accolite
Amazon
Samsung
Snapdeal
Linkedin
Intel
sliding-window
Dynamic Programming
Mathematical
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Bellman–Ford Algorithm | DP-23
Floyd Warshall Algorithm | DP-16
Matrix Chain Multiplication | DP-8
Travelling Salesman Problem | Set 1 (Naive and Dynamic Programming)
Sieve of Eratosthenes
Write a program to print all permutations of a given string
C++ Data Types
Set in C++ Standard Template Library (STL)
Merge two sorted arrays
Program to find GCD or HCF of two numbers