Open In App

Count ways to reach the nth stair using step 1, 2 or 3

Last Updated : 12 Dec, 2024
Comments
Improve
Suggest changes
57 Likes
Like
Report

A child is running up a staircase with n steps and can hop either 1 step, 2 steps, or 3 steps at a time. The task is to implement a method to count how many possible ways the child can run up the stairs.

Examples: 

Input: 4
Output: 7
Explanation: There are seven ways: {1, 1, 1, 1}, {1, 2, 1}, {2, 1, 1}, {1, 1, 2}, {2, 2}, {3, 1}, {1, 3}.

Input: 3
Output: 4
Explanation: There are four ways: {1, 1, 1}, {1, 2}, {2, 1}, {3}.

Using Recursion - O(3^n) Time and O(n) Space

There are n stairs, and a person is allowed to jump next stair, skip one stair or skip two stairs. So there are n stairs. So if a person is standing at i-th stair, the person can move to i+1, i+2, i+3-th stair. A recursive function can be formed where at current index i the function is recursively called for i+1, i+2 and i+3 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, i-2 or i-3 th stair.

countWays(n) = countWays(n-1) + countWays(n-2) + countWays(n-3)

Below is the implementation of the above approach:

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

int countWays(int n) {
    
    // Base case for 0th stair
    if (n == 0) return 1;
    
    // For invalid stair, return 0.
    if (n < 0) return 0;

    // Count number of ways to reach (n-1), (n-2),
    // (n-3) stair
    return countWays(n - 1) + countWays(n - 2) + countWays(n - 3);
}

int main() {
    
    int n = 4;
    cout << countWays(n) << endl;
    return 0;
}
C
// C program to count number of 
// ways to reach nth stair.
#include <stdio.h>

int countWays(int n) {
    
    // Base case for 0th stair
    if (n == 0) return 1;
    
    // For invalid stair, return 0.
    if (n < 0) return 0;

    // Count number of ways to reach (n-1), (n-2),
    // (n-3) stair
    return countWays(n - 1) + countWays(n - 2) + countWays(n - 3);
}

int main() {
    int n = 4;
    printf("%d\n", countWays(n));
    return 0;
}
Java
// Java program to count number of 
// ways to reach nth stair.

class GfG {

    static int countWays(int n) {
        
        // Base case for 0th stair
        if (n == 0) return 1;
        
        // For invalid stair, return 0.
        if (n < 0) return 0;

        // Count number of ways to reach (n-1), (n-2),
        // (n-3) stair
        return countWays(n - 1) + countWays(n - 2) + countWays(n - 3);
    }

    public static void main(String[] args) {
        int n = 4;
        System.out.println(countWays(n));
    }
}
Python
# Python program to count number of 
# ways to reach nth stair.

def countWays(n):
    
    # Base case for 0th stair
    if n == 0:
        return 1
    
    # For invalid stair, return 0.
    if n < 0:
        return 0

    # Count number of ways to reach (n-1), (n-2),
    # (n-3) stair
    return countWays(n - 1) + countWays(n - 2) + countWays(n - 3)

if __name__ == "__main__":
    n = 4
    print(countWays(n))
C#
// C# program to count number of 
// ways to reach nth stair.

using System;

class GfG {

    static int countWays(int n) {
        
        // Base case for 0th stair
        if (n == 0) return 1;
        
        // For invalid stair, return 0.
        if (n < 0) return 0;

        // Count number of ways to reach (n-1), (n-2),
        // (n-3) stair
        return countWays(n - 1) + countWays(n - 2) + countWays(n - 3);
    }

    static void Main(string[] args) {
        int n = 4;
        Console.WriteLine(countWays(n));
    }
}
JavaScript
// JavaScript program to count number of 
// ways to reach nth stair.

function countWays(n) {
    
    // Base case for 0th stair
    if (n === 0) return 1;
    
    // For invalid stair, return 0.
    if (n < 0) return 0;

    // Count number of ways to reach (n-1), (n-2),
    // (n-3) stair
    return countWays(n - 1) + countWays(n - 2) + countWays(n - 3);
}

const n = 4;
console.log(countWays(n));

Output
7

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:

Number of ways to reach the nth stair, i.e., countWays(n), depends on the optimal solutions of the subproblems countWays(n-1) , countWays(n-2) and countWays(n-3). By combining these optimal substructures, we can efficiently calculate the total number of ways 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 countWays(4), we recursively calculate countWays(3) and countWays(2) and countWays(1) which in turn will recursively compute countWays(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;

// Recursive function to count number
// of ways to reach nth stair
int countWaysRecur(int n, vector<int> &memo) {
    
    // Base case for 0th stair
    if (n == 0) return 1;
    
    // For invalid stair, return 0.
    if (n < 0) return 0;
    
    // If n'th stair is memoized,
    // return its value
    if (memo[n]!=-1) return memo[n];

    // Count number of ways to reach (n-1), (n-2),
    // (n-3)th stair and memoize it.
    return memo[n] = countWaysRecur(n-1, memo) + 
    countWaysRecur(n-2, memo) + countWaysRecur(n-3, memo);
}

int countWays(int n) {
    
    vector<int> memo(n+1, -1);
    return countWaysRecur(n, memo);
}

int main() {
    
    int n = 4;
    cout << countWays(n) << endl;
    return 0;
}
Java
// Java program to count number of 
// ways to reach nth stair.

import java.util.Arrays;

class GfG {

    // Recursive function to count number
    // of ways to reach nth stair
    static int countWaysRecur(int n, int[] memo) {
        
        // Base case for 0th stair
        if (n == 0) return 1;
        
        // For invalid stair, return 0.
        if (n < 0) return 0;
        
        // If n'th stair is memoized,
        // return its value
        if (memo[n] != -1) return memo[n];

        // Count number of ways to reach (n-1), (n-2),
        // (n-3)th stair and memoize it.
        return memo[n] = countWaysRecur(n - 1, memo) + 
                         countWaysRecur(n - 2, memo) + 
                         countWaysRecur(n - 3, memo);
    }

    static int countWays(int n) {
        int[] memo = new int[n + 1];
        Arrays.fill(memo, -1);
        return countWaysRecur(n, memo);
    }

    public static void main(String[] args) {
        int n = 4;
        System.out.println(countWays(n));
    }
}
Python
# Python program to count number of 
# ways to reach nth stair.

# Recursive function to count number
# of ways to reach nth stair
def countWaysRecur(n, memo):
    
    # Base case for 0th stair
    if n == 0:
        return 1
    
    # For invalid stair, return 0.
    if n < 0:
        return 0
    
    # If n'th stair is memoized,
    # return its value
    if memo[n] != -1:
        return memo[n]

    # Count number of ways to reach (n-1), (n-2),
    # (n-3)th stair and memoize it.
    memo[n] = countWaysRecur(n - 1, memo) + \
    countWaysRecur(n - 2, memo) + countWaysRecur(n - 3, memo)
    return memo[n]

def countWays(n):
    memo = [-1] * (n + 1)
    return countWaysRecur(n, memo)

if __name__ == "__main__":
    n = 4
    print(countWays(n))
C#
// C# program to count number of 
// ways to reach nth stair.

using System;

class GfG {

    // Recursive function to count number
    // of ways to reach nth stair
    static int countWaysRecur(int n, int[] memo) {
        
        // Base case for 0th stair
        if (n == 0) return 1;
        
        // For invalid stair, return 0.
        if (n < 0) return 0;
        
        // If n'th stair is memoized,
        // return its value
        if (memo[n] != -1) return memo[n];

        // Count number of ways to reach (n-1), (n-2),
        // (n-3)th stair and memoize it.
        return memo[n] = countWaysRecur(n - 1, memo) + 
                         countWaysRecur(n - 2, memo) + 
                         countWaysRecur(n - 3, memo);
    }

    static int countWays(int n) {
        int[] memo = new int[n + 1];
        Array.Fill(memo, -1);
        return countWaysRecur(n, memo);
    }

    static void Main(string[] args) {
        int n = 4;
        Console.WriteLine(countWays(n));
    }
}
JavaScript
// JavaScript program to count number of 
// ways to reach nth stair.

// Recursive function to count number
// of ways to reach nth stair
function countWaysRecur(n, memo) {
    
    // Base case for 0th stair
    if (n === 0) return 1;
    
    // For invalid stair, return 0.
    if (n < 0) return 0;
    
    // If n'th stair is memoized,
    // return its value
    if (memo[n] !== -1) return memo[n];

    // Count number of ways to reach (n-1), (n-2),
    // (n-3)th stair and memoize it.
    memo[n] = countWaysRecur(n - 1, memo) + 
                     countWaysRecur(n - 2, memo) + 
                     countWaysRecur(n - 3, memo);
    return memo[n];
}

function countWays(n) {
    let memo = new Array(n + 1).fill(-1);
    return countWaysRecur(n, memo);
}

const n = 4;
console.log(countWays(n));

Output
7

Using Bottom-Up DP (Tabulation) - O(n) Time and O(n) Space

The idea is to create a 1-D array, fill values for first three stairs and compute the values from 3 to n using the previous three results. For i=3 to n, do dp[i] = dp[i-1] + dp[i-2] + dp[i-3].

Below is the implementation of the above approach:

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

int countWays(int n) {

    // Base case for 0th and 1st stair
    if (n == 0 || n == 1)
        return 1;

    // base case for 2nd stair
    if (n == 2)
        return 2;

    // Initializing a matrix of size n+1
    vector<int> dp(n + 1);

    // insert ans values for 0,1,2 stair
    dp[0] = 1;
    dp[1] = 1;
    dp[2] = 2;

    // building dp in bottom up manner
    for (int i = 3; i <= n; i++) {
        dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];
    }

    return dp[n];
}

int main() {

    int n = 4;
    cout << countWays(n) << endl;
    return 0;
}
Java
// Java program to count number of 
// ways to reach nth stair.

import java.util.Arrays;

class GfG {

    static int countWays(int n) {
        
        // Base case for 0th and 1st stair
        if (n == 0 || n == 1) return 1;
        
        // base case for 2nd stair
        if (n == 2) return 2;
        
        // Initializing a matrix of size n+1
        int[] dp = new int[n + 1];
        
        // insert ans values for 0,1,2 stair
        dp[0] = 1;
        dp[1] = 1;
        dp[2] = 2;
        
        // building dp in bottom up manner
        for (int i = 3; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];
        }
        
        return dp[n];
    }

    public static void main(String[] args) {
        int n = 4;
        System.out.println(countWays(n));
    }
}
Python
# Python program to count number of 
# ways to reach nth stair.

def countWays(n):
    
    # Base case for 0th and 1st stair
    if n == 0 or n == 1:
        return 1
    
    # base case for 2nd stair
    if n == 2:
        return 2
    
    # Initializing a matrix of size n+1
    dp = [0] * (n + 1)
    
    # insert ans values for 0,1,2 stair
    dp[0] = 1
    dp[1] = 1
    dp[2] = 2
    
    # building dp in bottom up manner
    for i in range(3, n + 1):
        dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3]
    
    return dp[n]

if __name__ == "__main__":
    n = 4
    print(countWays(n))
C#
// C# program to count number of 
// ways to reach nth stair.

using System;

class GfG {

    static int countWays(int n) {
        
        // Base case for 0th and 1st stair
        if (n == 0 || n == 1) return 1;
        
        // base case for 2nd stair
        if (n == 2) return 2;
        
        // Initializing a matrix of size n+1
        int[] dp = new int[n + 1];
        
        // insert ans values for 0,1,2 stair
        dp[0] = 1;
        dp[1] = 1;
        dp[2] = 2;
        
        // building dp in bottom up manner
        for (int i = 3; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];
        }
        
        return dp[n];
    }

    static void Main(string[] args) {
        int n = 4;
        Console.WriteLine(countWays(n));
    }
}
JavaScript
// JavaScript program to count number of 
// ways to reach nth stair.

function countWays(n) {
    
    // Base case for 0th and 1st stair
    if (n === 0 || n === 1) return 1;
    
    // base case for 2nd stair
    if (n === 2) return 2;
    
    // Initializing a matrix of size n+1
    let dp = new Array(n + 1).fill(0);
    
    // insert ans values for 0,1,2 stair
    dp[0] = 1;
    dp[1] = 1;
    dp[2] = 2;
    
    // building dp in bottom up manner
    for (let i = 3; i <= n; i++) {
        dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];
    }
    
    return dp[n];
}

const n = 4;
console.log(countWays(n));

Output
7

Using Space Optimized DP - O(n) Time and O(1) Space

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

Below is the implementation of the above approach:

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

int countWays(int n) {

    // Base case for 0th and 1st stair
    if (n == 0 || n == 1)
        return 1;

    // base case for 2nd stair
    if (n == 2)
        return 2;

    // Variables to store values 
    // of previous 3 stairs.
    int prev1, prev2, prev3;

    // insert ans values for 0,1,2 stair
    prev3 = 1;
    prev2 = 1;
    prev1 = 2;

    // building dp in bottom up manner
    for (int i = 3; i <= n; i++) {
        int val = prev1 + prev2 + prev3;

        // Replace previous stair values
        // with next stairs.
        prev3 = prev2;
        prev2 = prev1;
        prev1 = val;
    }

    return prev1;
}

int main() {

    int n = 4;
    cout << countWays(n) << endl;
    return 0;
}
C
// C program to count number of
// ways to reach nth stair.
#include <stdio.h>

int countWays(int n) {

    // Base case for 0th and 1st stair
    if (n == 0 || n == 1)
        return 1;

    // base case for 2nd stair
    if (n == 2)
        return 2;

    // Variables to store values 
    // of previous 3 stairs.
    int prev1, prev2, prev3;

    // insert ans values for 0,1,2 stair
    prev3 = 1;
    prev2 = 1;
    prev1 = 2;

    // building dp in bottom up manner
    for (int i = 3; i <= n; i++) {
        int val = prev1 + prev2 + prev3;

        // Replace previous stair values
        // with next stairs.
        prev3 = prev2;
        prev2 = prev1;
        prev1 = val;
    }

    return prev1;
}

int main() {

    int n = 4;
    printf("%d\n", countWays(n));
    return 0;
}
Java
// Java program to count number of
// ways to reach nth stair.

class GfG {

    static int countWays(int n) {

        // Base case for 0th and 1st stair
        if (n == 0 || n == 1)
            return 1;

        // base case for 2nd stair
        if (n == 2)
            return 2;

        // Variables to store values 
        // of previous 3 stairs.
        int prev1, prev2, prev3;

        // insert ans values for 0,1,2 stair
        prev3 = 1;
        prev2 = 1;
        prev1 = 2;

        // building dp in bottom up manner
        for (int i = 3; i <= n; i++) {
            int val = prev1 + prev2 + prev3;

            // Replace previous stair values
            // with next stairs.
            prev3 = prev2;
            prev2 = prev1;
            prev1 = val;
        }

        return prev1;
    }

    public static void main(String[] args) {

        int n = 4;
        System.out.println(countWays(n));
    }
}
Python
# Python program to count number of
# ways to reach nth stair.

def countWays(n):

    # Base case for 0th and 1st stair
    if n == 0 or n == 1:
        return 1

    # base case for 2nd stair
    if n == 2:
        return 2

    # Variables to store values 
    # of previous 3 stairs.
    prev3 = 1
    prev2 = 1
    prev1 = 2

    # building dp in bottom up manner
    for i in range(3, n + 1):
        val = prev1 + prev2 + prev3

        # Replace previous stair values
        # with next stairs.
        prev3 = prev2
        prev2 = prev1
        prev1 = val

    return prev1

if __name__ == "__main__":
    n = 4
    print(countWays(n))
C#
// C# program to count number of
// ways to reach nth stair.

using System;

class GfG {

    static int countWays(int n) {

        // Base case for 0th and 1st stair
        if (n == 0 || n == 1)
            return 1;

        // base case for 2nd stair
        if (n == 2)
            return 2;

        // Variables to store values 
        // of previous 3 stairs.
        int prev1, prev2, prev3;

        // insert ans values for 0,1,2 stair
        prev3 = 1;
        prev2 = 1;
        prev1 = 2;

        // building dp in bottom up manner
        for (int i = 3; i <= n; i++) {
            int val = prev1 + prev2 + prev3;

            // Replace previous stair values
            // with next stairs.
            prev3 = prev2;
            prev2 = prev1;
            prev1 = val;
        }

        return prev1;
    }

    static void Main() {

        int n = 4;
        Console.WriteLine(countWays(n));
    }
}
JavaScript
// JavaScript program to count number of
// ways to reach nth stair.

function countWays(n) {

    // Base case for 0th and 1st stair
    if (n === 0 || n === 1)
        return 1;

    // base case for 2nd stair
    if (n === 2)
        return 2;

    // Variables to store values 
    // of previous 3 stairs.
    let prev3 = 1, prev2 = 1, prev1 = 2;

    // building dp in bottom up manner
    for (let i = 3; i <= n; i++) {
        let val = prev1 + prev2 + prev3;

        // Replace previous stair values
        // with next stairs.
        prev3 = prev2;
        prev2 = prev1;
        prev1 = val;
    }

    return prev1;
}

let n = 4;
console.log(countWays(n));

Output
7

Using Matrix Exponentiation - O(log n) Time and O(1) Space

The recurrence relation for a given step is given as countWays(n) = countWays(n-1) + countWays(n-2) + countWays(n-3) starting with countWays(0)=1, countWays(1)=1, countWays(2)=2.

Refer to Matrix Exponentiation to understand how matrix exponentiation works.

Below is the implementation of the above approach:

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

// Function to multiply two 3x3 matrices
void multiply(vector<vector<int> >& a,
              vector<vector<int> >& b) {
                  
    // Matrix to store the result
    vector<vector<int> > c(3, vector<int>(3));

    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            for (int k = 0; k < 3; k++) {
                c[i][j]
                    = (c[i][j] + ((a[i][k]) * (b[k][j])));
            }
        }
    }

    // Copy the result back to the first matrix
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            a[i][j] = c[i][j];
        }
    }
}

// Function to calculate (Matrix M) ^ expo
vector<vector<int> >
power(vector<vector<int> > m, int expo) {
    
    // Initialize result with identity matrix
    vector<vector<int> > ans
        = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } };

    // Fast Exponentiation
    while (expo) {
        if (expo & 1)
            multiply(ans, m);
        multiply(m, m);
        expo >>= 1;
    }

    return ans;
}

// function to count number of
// ways to reach nth stair.
int countWays(int n) {

    // base condition
    if (n == 0 || n == 1)
        return 1;

    // Matrix M to generate the next step value.
    vector<vector<int> > m
        = { { 1, 1, 1 }, { 1, 0, 0 }, { 0, 1, 0 } };

    // first 3 values of steps are:
    // findWays(0) = 1
    // findWays(1) = 1
    // findWays(2) = 2
    // f = {{findWays(2), 0, 0}, {findWays(1), 0, 0}, 
    //  {findWays(0), 0,0}}
    vector<vector<int> > f
        = { { 2, 0, 0 }, { 1, 0, 0 }, { 1, 0, 0 } };

    vector<vector<int> > res = power(m, n - 2);
    multiply(res, f);

    return res[0][0];
}

int main() {

    int n = 4;
    cout << countWays(n) << endl;
    return 0;
}
Java
// Java program to count number of
// ways to reach nth stair.

import java.util.Arrays;

class GfG {

    // Function to multiply two 3x3 matrices
    static void multiply(int[][] a, int[][] b) {

        // Matrix to store the result
        int[][] c = new int[3][3];

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                for (int k = 0; k < 3; k++) {
                    c[i][j] = c[i][j] + (a[i][k] * b[k][j]);
                }
            }
        }

        // Copy the result back to the first matrix
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                a[i][j] = c[i][j];
            }
        }
    }

    // Function to calculate (Matrix M) ^ expo
    static int[][] power(int[][] m, int expo) {

        // Initialize result with identity matrix
        int[][] ans = { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} };

        // Fast Exponentiation
        while (expo != 0) {
            if ((expo & 1) != 0) multiply(ans, m);
            multiply(m, m);
            expo >>= 1;
        }

        return ans;
    }

    // function to count number of
    // ways to reach nth stair.
    static int countWays(int n) {

        // base condition
        if (n == 0 || n == 1) return 1;

        // Matrix M to generate the next step value.
        int[][] m = { {1, 1, 1}, {1, 0, 0}, {0, 1, 0} };

        // first 3 values of steps are:
        // findWays(0) = 1
        // findWays(1) = 1
        // findWays(2) = 2
        // f = {{findWays(2), 0, 0}, {findWays(1), 0, 0}, 
        //  {findWays(0), 0,0}}
        int[][] f = { {2, 0, 0}, {1, 0, 0}, {1, 0, 0} };

        int[][] res = power(m, n - 2);
        multiply(res, f);

        return res[0][0];
    }

    public static void main(String[] args) {
        int n = 4;
        System.out.println(countWays(n));
    }
}
Python
# Python program to count number of
# ways to reach nth stair.

# Function to multiply two 3x3 matrices
def multiply(a, b):
    
    # Matrix to store the result
    c = [[0] * 3 for _ in range(3)]

    for i in range(3):
        for j in range(3):
            for k in range(3):
                c[i][j] += a[i][k] * b[k][j]

    # Copy the result back to the first matrix
    for i in range(3):
        for j in range(3):
            a[i][j] = c[i][j]

# Function to calculate (Matrix M) ^ expo
def power(m, expo):
    
    # Initialize result with identity matrix
    ans = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]

    # Fast Exponentiation
    while expo:
        if expo & 1:
            multiply(ans, m)
        multiply(m, m)
        expo >>= 1

    return ans

# function to count number of
# ways to reach nth stair.
def countWays(n):
    
    # base condition
    if n == 0 or n == 1:
        return 1

    # Matrix M to generate the next step value.
    m = [[1, 1, 1], [1, 0, 0], [0, 1, 0]]

    # first 3 values of steps are:
    # findWays(0) = 1
    # findWays(1) = 1
    # findWays(2) = 2
    # f = {{findWays(2), 0, 0}, {findWays(1), 0, 0}, 
    #  {findWays(0), 0,0}}
    f = [[2, 0, 0], [1, 0, 0], [1, 0, 0]]

    res = power(m, n - 2)
    multiply(res, f)

    return res[0][0]

if __name__ == "__main__":
    n = 4
    print(countWays(n))
C#
// C# program to count number of
// ways to reach nth stair.

using System;

class GfG {

    // Function to multiply two 3x3 matrices
    static void multiply(int[,] a, int[,] b) {
        
        // Matrix to store the result
        int[,] c = new int[3, 3];

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                for (int k = 0; k < 3; k++) {
                    c[i, j] += a[i, k] * b[k, j];
                }
            }
        }

        // Copy the result back to the first matrix
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                a[i, j] = c[i, j];
            }
        }
    }

    // Function to calculate (Matrix M) ^ expo
    static int[,] power(int[,] m, int expo) {
        
        // Initialize result with identity matrix
        int[,] ans = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } };

        // Fast Exponentiation
        while (expo != 0) {
            if ((expo & 1) != 0)
                multiply(ans, m);
            multiply(m, m);
            expo >>= 1;
        }

        return ans;
    }

    // function to count number of
    // ways to reach nth stair.
    static int countWays(int n) {

        // base condition
        if (n == 0 || n == 1)
            return 1;

        // Matrix M to generate the next step value.
        int[,] m = { { 1, 1, 1 }, { 1, 0, 0 }, { 0, 1, 0 } };

        // first 3 values of steps are:
        // findWays(0) = 1
        // findWays(1) = 1
        // findWays(2) = 2
        // f = {{findWays(2), 0, 0}, {findWays(1), 0, 0}, 
        //  {findWays(0), 0,0}}
        int[,] f = { { 2, 0, 0 }, { 1, 0, 0 }, { 1, 0, 0 } };

        int[,] res = power(m, n - 2);
        multiply(res, f);

        return res[0, 0];
    }

    static void Main(string[] args) {
        int n = 4;
        Console.WriteLine(countWays(n));
    }
}
JavaScript
// JavaScript program to count number of 
// ways to reach nth stair

// Function to multiply two 3x3 matrices
function multiply(a, b) {
    
    // Matrix to store the result
    let c = Array.from({ length: 3 }, () => Array(3).fill(0));

    for (let i = 0; i < 3; i++) {
        for (let j = 0; j < 3; j++) {
            for (let k = 0; k < 3; k++) {
                c[i][j] += a[i][k] * b[k][j];
            }
        }
    }

    // Copy the result back to the first matrix
    for (let i = 0; i < 3; i++) {
        for (let j = 0; j < 3; j++) {
            a[i][j] = c[i][j];
        }
    }
}

// Function to calculate (Matrix M) ^ expo
function power(m, expo) {
    
    // Initialize result with identity matrix
    let ans = [[1, 0, 0], [0, 1, 0], [0, 0, 1]];

    // Fast Exponentiation
    while (expo) {
        if (expo & 1) {
            multiply(ans, m);
        }
        multiply(m, m);
        expo >>= 1;
    }

    return ans;
}

// function to count number of 
// ways to reach nth stair.
function countWays(n) {

    // base condition
    if (n === 0 || n === 1) return 1;

    // Matrix M to generate the next step value.
    let m = [[1, 1, 1], [1, 0, 0], [0, 1, 0]];

    // first 3 values of steps are:
    // findWays(0) = 1
    // findWays(1) = 1
    // findWays(2) = 2
    // f = {{findWays(2), 0, 0}, {findWays(1), 0, 0}, 
    //  {findWays(0), 0,0}}
    let f = [[2, 0, 0], [1, 0, 0], [1, 0, 0]];

    let res = power(m, n - 2);
    multiply(res, f);

    return res[0][0];
}

let n = 4;
console.log(countWays(n));

Output
7

Article Tags :

Explore