Thursday, December 26, 2024
Google search engine
HomeData Modelling & AIClimbing Stairs to reach at the top.

Climbing Stairs to reach at the top.

There are n stairs, a person standing at the bottom wants to climb stairs to reach the nth stair. The person can climb either 1 stair or 2 stairs at a time, the task is to count the number of ways that a person can reach at the top.
 

stairs

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)

Climbing Stairs using Recursion:

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 Recurrence relation 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:

nthfibonacciseriesdynamicprogramming

So we can use the function for Fibonacci numbers to find the value of ways(n).

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;
  
// A simple recursive program to
// find N'th fibonacci number
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
int countWays(int s) { return fib(s + 1); }
  
// Driver Code
int main()
{
    int s = 4;
  
    cout << "Number of ways = " << countWays(s);
  
    return 0;
}
  
// This code is contributed by shubhamsingh10


C




// C Program to count number of
// ways to reach Nth stair
#include <stdio.h>
  
// A simple recursive program to
// find n'th fibonacci number
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
int countWays(int s) { return fib(s + 1); }
  
// Driver program to test above functions
int main()
{
    int s = 4;
    printf("Number of ways = %d", countWays(s));
    getchar();
    return 0;
}


Java




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




# Python program to count
# ways to reach nth stair
  
# Recursive function to find
# Nth fibonacci number
  
  
def fib(n):
    if n <= 1:
        return n
    return fib(n-1) + fib(n-2)
  
# Returns no. of ways to
# reach sth stair
  
  
def countWays(s):
    return fib(s + 1)
  
  
# Driver program
s = 4
print "Number of ways = ",
print countWays(s)
  
# Contributed by Harshit Agrawal


C#




// C# program to count the
// number of ways to reach
// n'th stair
using 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


Javascript




<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 number
function fib(n)
{
if (n <= 1)
    return n;
return fib(n - 1) + 
       fib(n - 2);
}
  
// Returns number of 
// ways to reach s'th stair
function countWays(s)
{
    return fib(s + 1);
}
  
// Driver Code
let s = 4;
document.write("Number of ways = " + countWays(s));
  
// This code is contributed
// by _saurabh_jaiswal
</script>


PHP




<?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 number
function fib($n)
{
if ($n <= 1)
    return $n;
return fib($n - 1) + 
       fib($n - 2);
}
  
// Returns number of 
// ways to reach s'th stair
function countWays($s)
{
    return fib($s + 1);
}
  
// Driver Code
$s = 4;
echo "Number of ways = "
           countWays($s);
  
// This code is contributed
// by m_kit
?>


Output

Number of ways = 5

Time Complexity: O(2n) , because at each stair there are two choices and there are total of n stairs.
Auxiliary Space: O(n), because of recursive stack space.

Climbing Stairs Problem using Dynamic Programming (Memoization) :

The above recursive solution has Optimal Substructure and Overlapping Subproblems so Dynamic programming (Memoization) can be used to solve the problem. So a 1D array can be used to store results of previously solved subproblems.

Follow the below steps to Implement the idea:

  • Create a 1D dp where dp[i] represent the number of ways to reach the ith stair from the bottom.
  • Check if answer for subproblem already exist or not in dp.
  • Recursively call for subproblems and store their result in dp (i.e, dp[n] = countWays(n – 1, dp) + countWays(n – 2, dp)).
  • Finally, return dp[n], as it will store the answer for input n.

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;
  
// A simple recursive function to find number of ways to
// reach the nth stair
int countWays(int n, int dp[])
{
    if (n <= 1)
        return dp[n] = 1;
  
    if (dp[n] != -1) {
        return dp[n];
    }
    dp[n] = countWays(n - 1, dp) + countWays(n - 2, dp);
    return dp[n];
}
  
// Driver Code
int main()
{
    int n = 4;
    int dp[n + 1];
    memset(dp, -1, sizeof dp);
    cout << "Number of ways = " << countWays(n, dp);
    return 0;
}


C




// C program to count number of ways to reach Nth stair
#include <stdio.h>
#include <string.h>
  
// A simple recursive function to find number of ways to
// reach the nth stair
int countWays(int n, int dp[])
{
    if (n <= 1)
        return dp[n] = 1;
  
    if (dp[n] != -1) {
        return dp[n];
    }
    dp[n] = countWays(n - 1, dp) + countWays(n - 2, dp);
    return dp[n];
}
  
// Driver Code
int main()
{
    int n = 4;
    int dp[n + 1];
    memset(dp, -1, sizeof dp);
    printf("Number of ways = %d", countWays(n, dp));
    return 0;
}


Java




// Java program to count number of
// ways to reach Nth stair
class GFG {
  
    // A simple recursive function to find number of ways to
    // reach the nth stair
    static int countWays(int n, int dp[])
    {
        if (n <= 1)
            return dp[n] = 1;
  
        if (dp[n] != -1) {
            return dp[n];
        }
        dp[n] = countWays(n - 1, dp) + countWays(n - 2, dp);
        return dp[n];
    }
  
    // Driver code
    public static void main(String[] args)
    {
        int n = 4;
        int[] dp = new int[n + 1];
        for (int i = 0; i < n + 1; i++) {
            dp[i] = -1;
        }
        System.out.println(countWays(n, dp));
    }
}
  
// This code is contributed by Karandeep1234


Python3




# Python program to count number of
# ways to reach Nth stair
  
# A simple recursive function to find number of ways to reach the nth stair
  
  
def countWays(n, dp):
  
    if (n <= 1):
        return 1
  
    if(dp[n] != -1):
        return dp[n]
  
    dp[n] = countWays(n - 1, dp) + countWays(n - 2, dp)
    return dp[n]
  
  
# Driver Code
n = 4
dp = [-1 for i in range(n + 1)]
print("Number of ways = " + str(countWays(n, dp)))


C#




// C# program to implement
// the above approach
using System;
  
class GFG {
  
    // A simple recursive function to find number of ways to
    // reach the nth stair
    static int countWays(int n, int[] dp)
    {
        if (n <= 1)
            return dp[n] = 1;
  
        if (dp[n] != -1) {
            return dp[n];
        }
        dp[n] = countWays(n - 1, dp) + countWays(n - 2, dp);
        return dp[n];
    }
  
    // Driver Code
    public static void Main()
    {
        int n = 4;
        int[] dp = new int[n + 1];
        for (int i = 0; i < n + 1; i++) {
            dp[i] = -1;
        }
        Console.Write("Number of ways = "
                      + countWays(n, dp));
    }
}
  
// This code is contributed by sanjoy_62.


Javascript




// A simple recursive function to find number of ways to reach the nth stair
  
function countWays(n, dp)
{
    if (n <= 1)
        return dp[n] = 1;
    
    if(dp[n] != -1 ){
        return dp[n] ;
    }
    dp[n] = countWays(n - 1, dp) + countWays(n - 2, dp);
    return  dp[n] ;
}
  
  
// Driver Code
  
let n = 4;
 let dp = new Array(n+1).fill(-1) ;
console.log("Number of ways = " + countWays(n,dp));


Output

Number of ways = 5

Time Complexity: O(n)
Auxiliary Space: O(n)

Climbing Stairs using Dynamic Programming (Tabulation):

Create a table dp[] in bottom up manner using the following relation: 

dp[i] = dp[i-1] + dp[i-2]

Follow the below steps to Implement the idea:

  • Create a 1D dp where dp[i] represent the number of ways to reach the ith stair from the bottom.
  • Initialise dp[0] = 1, as there is only one way for n = 0 and dp[1] = 2 as there are only 2 ways for input n = 2.
  • Now for each i >= 2, dp[i] = dp[i-1]+dp[i-2]

Below code implements the above approach: 

C++




// 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 function to find number of ways to reach the nth stair
int countWays(int n)
{
    int dp[n + 1];
    dp[0] = 1;
    dp[1] = 1;
  
    for (int i = 2; i <= n; i++)
        dp[i] = dp[i - 1] + dp[i - 2];
    return dp[n];
}
  
// Driver code
int main()
{
    int n = 4;
  
    cout << "Number of ways = " << countWays(n);
  
    return 0;
}


Java




// 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 function to find number of ways to reach the nth
    // stair
    static int countWays(int n)
    {
        int dp[] = new int[n + 1];
        dp[0] = 1;
        dp[1] = 1;
  
        for (int i = 2; i <= n; i++)
            dp[i] = dp[i - 1] + dp[i - 2];
        return dp[n];
    }
  
    // Driver method
    public static void main(String[] args)
    {
        int n = 4;
        System.out.println("Number of ways = "
                           + countWays(n));
    }
}


Python




# A program to count the number of
# ways to reach n'th stair
  
# A function to find number of ways to reach the nth stair
  
  
def countWays(n):
    # Creates list res with all elements 0
    dp = [0 for x in range(n+1)]
    dp[0], dp[1] = 1, 1
  
    for i in range(2, n+1):
        dp[i] = dp[i-1]+dp[i-2]
    return dp[n]
  
  
# Driver Program
n = 4
print "Number of ways =", countWays(n)


C#




// C# program to count number
// of ways to reach n'th stair when
// a person can climb 1, 2, ..m
// stairs at a time
using System;
class GFG {
  
    // A function to find number of ways to reach the nth
    // stair
    static int countWays(int n)
    {
        int[] dp = new int[n + 1];
        dp[0] = 1;
        dp[1] = 1;
  
        for (int i = 2; i <= n; i++)
            dp[i] = dp[i - 1] + dp[i - 2];
        return dp[n];
    }
  
    // Driver Code
    public static void Main()
    {
        int n = 4;
        Console.WriteLine("Number of ways = "
                          + countWays(n));
    }
}


Javascript




// A function to find number of ways to reach the nth stair
  
function countWays(n)
{
    let dp = [];
    dp[0] = 1; 
    dp[1] = 1;
    for (let i = 2; i <=n; i++)
    {
        dp[i]=dp[i-1]+dp[i-2];
    }
    return dp[n];
}
  
  
    // Driver Code
    let n=4;
    console.log("Number of ways = " + countWays(n));


Output

Number of ways = 5

Time Complexity: O(n)
Auxiliary Space: O(n)

Coin change Problem using the Space Optimized approach:

In the above approach it can be seen that dp[i] only depends on previous states. We can optimize the space complexity of the dynamic programming solution to O(1) by using only two variables prev1 and prev2 to keep track of the previous two values of dp[i-1] and dp[i-2]. Since we only need these two values to calculate the next value, we don’t need to store the entire array.

Below is the code implementation of the above idea:

C++




// C++ program to count the number of ways to reach at top
// When a person climbing on stairs
  
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
  
int countWays(int n)
{
    // declaring  two variables to store the count
    int prev = 1;
    int prev2 = 1;
    // Running for loop to count all possible ways
    for (int i = 2; i <= n; i++) {
        int curr = prev + prev2;
        prev2 = prev;
        prev = curr;
    }
    return prev;
}
int main()
{
    int n = 4;
  
    cout << "Number of Ways : " << countWays(n);
  
    return 0;
}
// This code is contributed by Neeraj Chaubey


Java




// Java program to count the number of ways to reach at top
// When a person climbing on stairs
  
public class Solution {
  
    static int countWays(int n)
    {
        // declaring  two variables to store the count
        int prev = 1;
        int prev2 = 1;
        // Running for loop to count all possible ways
        for (int i = 2; i <= n; i++) {
            int curr = prev + prev2;
            prev2 = prev;
            prev = curr;
        }
        return prev;
    }
    public static void main(String[] args)
    {
        int n = 4;
        System.out.println("Number of Ways : "
                           + countWays(n));
    }
}
// This code is contributed by karandeep1234


Python3




# Python program to count the number of ways to reach at top
# When a person climbing on stairs
  
  
def countWays(n):
    # declaring  two variables to store the count
    prev = 1
    prev2 = 1
    # Running for loop to count all possible ways
    for i in range(2, n+1):
        curr = prev + prev2
        prev2 = prev
        prev = curr
    return prev
  
  
n = 4
print("Number of Ways : ", countWays(n))


C#




// C# program to count the number of ways to reach at top
// When a person climbing on stairs
using System;
  
public class GFG {
  
    public static int countWays(int n)
    {
        // declaring  two variables to store the count
        int prev = 1;
        int prev2 = 1;
        // Running for loop to count all possible ways
        for (int i = 2; i <= n; i++) {
            int curr = prev + prev2;
            prev2 = prev;
            prev = curr;
        }
        return prev;
    }
    public static void Main(string[] args)
    {
        int n = 4;
        Console.WriteLine("Number of Ways : "
                          + countWays(n));
    }
}
// This code is contributed by karandeep1234


Javascript




// JavaScript program to count the number of ways to reach at top
// When a person climbing on stairs
  
function countWays(n) {
    // declaring  two variables to store the count
    let prev = 1;
    let prev2 = 1;
    // Running for loop to count all possible ways
    for (let i = 2; i <= n; i++) {
        let curr = prev + prev2;
        prev2 = prev;
        prev = curr;
    }
    return prev;
}
  
let n = 4;
document.write("Number of Ways: ", countWays(n));


Output

Number of Ways : 5

Time Complexity: O(N)
Auxiliary Space: O(1)

Coin change Problem using Mathematics:

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.

In this method, simply count the number of sets having 2, which will be equal to n/2. So total number of ways will be n/2+1 (one is added to incude the set which does not contain any 2)

Below is the implementation of above approach:

C++




#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;
}


Java




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


Python3




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


C#




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


Javascript




<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>


Output

Number of ways when order of steps does not matter is : 3

Time Complexity : O(1)
Auxiliary Space : O(1)

Coin change Problem using Matrix Exponentiation:

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:

0 1
1 1

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):

1
2

As an example, For n= 4: 

F(4) = C3F(1)

C3

1 2
2 3

Hence, C3F(1) = 

5
8

C++




#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 matrices
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;
}
  
// Computes A^n
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;
}
  
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


Java




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


Python3




# Computes A*B
# where A,B are square matrices
  
  
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
  
# Computes A^n
  
  
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 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 code
if __name__ == '__main__':
    n = 4
    print("Number of ways = ", ways(n), "")
  
# This code is contributed by gauravrajput1


C#




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


Javascript




<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>


Output

Number of ways = 5

Time Complexity: O(Log n)
Auxiliary Space: O(1)

Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

RELATED ARTICLES

Most Popular

Recent Comments