📌  相关文章
📜  数数到达第 n 级楼梯的方法

📅  最后修改于: 2021-09-17 16:16:19             🧑  作者: Mango

有n个楼梯,站在底部的人想要到达顶部。该人一次可以爬 1 个楼梯或 2 个楼梯。数一数,人能登顶。

楼梯

考虑图中所示的示例。 n 的值为 3。有 3 种方法可以到达顶部。该图取自 Easier Fibonacci 谜题

例子:

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) 

方法一第一种方法使用递归技术来解决这个问题。
方法:我们可以很容易地发现上述问题中的递归性质。该人可达到n的任一第(n-1)楼梯或从第(n-2)楼梯楼梯。因此,对于每个楼梯n ,我们尝试找出到达n-1 th st 和n-2 th楼梯的方法数量,并将它们相加以给出n th楼梯的答案。因此,这种方法的表达式是:

ways(n) = ways(n-1) + ways(n-2)

上面的表达式实际上是斐波那契数的表达式,但是有一点需要注意,way(n) 的值等于fibonacci(n+1)。

ways(1) = fib(2) = 1
ways(2) = fib(3) = 2
ways(3) = fib(4) = 3

为了更好地理解,让我们参考下面的递归树 -:

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)

所以我们可以使用斐波那契数的函数来找到 way(n) 的值。以下是上述想法的 C++ 实现。

C++
// C++ program to count number of
// ways to reach Nth stair
#include 
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 C
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 
 
// 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


PHP


Javascript


C++
// 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 
using namespace std;
 
// A recursive function used by countWays
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
int countWays(int s, int m)
{
    return countWaysUtil(s + 1, m);
}
 
// Driver code
int main()
{
    int s = 4, m = 2;
    cout << "Number of ways = " << countWays(s, m);
 
    return 0;
}
 
// This code is contribute by shubhamsingh10


C
// 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 
 
// A recursive function used by countWays
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
int 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;
}


Java
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 */


Python
# A program to count the number of ways
# to reach n'th stair
 
# Recursive function used by countWays
def 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 program
s, m = 4, 2
print "Number of ways =", countWays(s, m)
 
# Contributed by Harshit Agrawal


PHP


Javascript


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 
using namespace std;
 
// A recursive function used by countWays
int 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 stair
int countWays(int s, int m)
{
    return countWaysUtil(s + 1, m);
}
 
// Driver code
int main()
{
    int s = 4, m = 2;
     
    cout << "Number of ways = "
         << countWays(s, m);
          
    return 0;
}
 
// This code is contributed by shubhamsingh10


C
// 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 
 
// A recursive function used by countWays
int 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 stair
int 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;
}


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


Python
# A program to count the number of
# ways to reach n'th stair
 
# Recursive function used by countWays
def 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 stair
def countWays(s, m):
    return countWaysUtil(s + 1, m)
     
# Driver Program
s, m = 4, 2
print "Number of ways =", countWays(s, m)
     
# Contributed by Harshit Agrawal


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


Javascript


C++
// 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 
using namespace std;
 
// Returns number of ways
// to reach s'th stair
int 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 Code
int main()
{
    int n = 5, m = 3;
    cout << "Number of ways = "
         << countWays(n, m);
    return 0;
}
 
// This code is contributed by shubhamsingh10


C
// 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 
 
// Returns number of ways
// to reach s'th stair
int 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 Code
int main()
{
    int n = 5, m = 3;
    printf("Number of ways = %d",
           countWays(n, m));
    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{
     
// Returns number of ways
// to reach s'th stair
static 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 Code
public 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
# 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 stair
def 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 Code
n = 5
m = 3
 
print('Number of ways =', countWays(n, m))
 
# This code is contributed by 31ajaydandge


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{
     
// Returns number of ways
// to reach s'th stair
static 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 Code
public static void Main()
{
    int n = 5, m = 3;
    Console.WriteLine("Number of ways = " +
                      countWays(n, m));
}
}
 
// This code is contributed by equbalzeeshan


Javascript


C++
#include 
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)<


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


C++
#include 
using namespace std;
typedef vector > 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(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 F(3);
    F[1] = 1;
    F[2] = 2;
    int K = 2;
    long long MOD = 1000000007;
    // create K*K matrix
    matrix C(K + 1, vector(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


C++
#include 
using namespace std;
typedef vector > 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(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 initialize(vector A)
{
    // Initializes the base vector F(1)
   
    int K = A[A.size() - 1]; // Assuming A is sorted
    vector F(K + 1, 0);
    vector 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 A, int n)
{
    int K = A[A.size() - 1]; // Assuming A is sorted
    vector F = initialize(A); // O(m^2*K)
    int MOD = 1000000007;
    // create K*K matrix
    matrix C(K + 1, vector(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 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


输出:

Number of ways = 5

复杂度分析:

  • 时间复杂度: O(2^n)
    由于冗余计算,上述实现的时间复杂度是指数级的(黄金比例增加到 n 次方)。可以使用前面讨论的 Fibonacci函数优化来优化它以在 O(Logn) 时间内工作。
  • 辅助空间: O(1)

问题的概括
如果一个人可以爬上 m 个楼梯,对于给定的值 m,如何计算方法的数量。例如,如果 m 为 4,则此人一次可以爬 1 阶或 2 阶或 3 阶或 4 阶。

方法:对于上述方法的推广,可以使用以下递归关系。

ways(n, m) = ways(n-1, m) + ways(n-2, m) + ... ways(n-m, m) 

在这种到达n楼梯的方法中,尝试从当前楼梯爬上所有可能数量小于等于 n 的楼梯。

以下是上述递归的实现。

C++

// 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 
using namespace std;
 
// A recursive function used by countWays
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
int countWays(int s, int m)
{
    return countWaysUtil(s + 1, m);
}
 
// Driver code
int main()
{
    int s = 4, m = 2;
    cout << "Number of ways = " << countWays(s, m);
 
    return 0;
}
 
// This code is contribute by shubhamsingh10

C

// 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 
 
// A recursive function used by countWays
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
int 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;
}

Java

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

Python

# A program to count the number of ways
# to reach n'th stair
 
# Recursive function used by countWays
def 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 program
s, m = 4, 2
print "Number of ways =", countWays(s, m)
 
# Contributed by Harshit Agrawal

PHP


Javascript


输出:

Number of ways = 5

复杂度分析:

  • 时间复杂度: O(2^n)
    由于冗余计算,上述实现的时间复杂度是指数级的(黄金比例提高到 n 次方)。可以使用动态规划将其优化为 O(m*n)。
  • 辅助空间: O(1)

方法 2该方法使用动态规划技术来得出解决方案。

方法:我们使用以下关系以自下而上的方式创建一个表res[]

res[i] = res[i] + res[i-j] for every (i-j) >= 0

使得阵列的i指数将包含的路的数目需要达到i步骤考虑攀登的所有可能性(即,从1到i)。

下面的代码实现了上述方法:

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 
using namespace std;
 
// A recursive function used by countWays
int 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 stair
int countWays(int s, int m)
{
    return countWaysUtil(s + 1, m);
}
 
// Driver code
int main()
{
    int s = 4, m = 2;
     
    cout << "Number of ways = "
         << countWays(s, m);
          
    return 0;
}
 
// This code is contributed by shubhamsingh10

C

// 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 
 
// A recursive function used by countWays
int 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 stair
int 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;
}

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

Python

# A program to count the number of
# ways to reach n'th stair
 
# Recursive function used by countWays
def 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 stair
def countWays(s, m):
    return countWaysUtil(s + 1, m)
     
# Driver Program
s, m = 4, 2
print "Number of ways =", countWays(s, m)
     
# Contributed by Harshit Agrawal

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


Javascript


输出:

Number of ways = 5

复杂度分析:

  • 时间复杂度: O(m*n)
  • 辅助空间: O(n)

方法三第三种方法使用滑动窗口的技术来得出解决方案。
方法:该方法有效地实现了上述动态规划方法。
在第i楼梯的这种方法中,我们保留了最后m 个可能的楼梯总和的窗口,我们可以从中爬到第i楼梯。我们没有运行内循环,而是将内循环的结果保存在一个临时变量中。我们删除前一个窗口的元素并添加当前窗口的元素并更新总和。

下面的代码实现了上面的想法

C++

// 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 
using namespace std;
 
// Returns number of ways
// to reach s'th stair
int 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 Code
int main()
{
    int n = 5, m = 3;
    cout << "Number of ways = "
         << countWays(n, m);
    return 0;
}
 
// This code is contributed by shubhamsingh10

C

// 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 
 
// Returns number of ways
// to reach s'th stair
int 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 Code
int main()
{
    int n = 5, m = 3;
    printf("Number of ways = %d",
           countWays(n, m));
    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{
     
// Returns number of ways
// to reach s'th stair
static 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 Code
public 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

蟒蛇3

# 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 stair
def 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 Code
n = 5
m = 3
 
print('Number of ways =', countWays(n, m))
 
# This code is contributed by 31ajaydandge

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{
     
// Returns number of ways
// to reach s'th stair
static 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 Code
public static void Main()
{
    int n = 5, m = 3;
    Console.WriteLine("Number of ways = " +
                      countWays(n, m));
}
}
 
// This code is contributed by equbalzeeshan

Javascript


输出:

Number of ways = 13

复杂度分析:

  • 时间复杂度: O(n)
  • 辅助空间: O(n)

方法 4 :第四种方法使用简单的数学方法,但这仅适用于在计算步数时(顺序无关紧要)的问题

方法:在这种方法中,我们简单地计算具有 2 的集合的数量。

C++

#include 
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)<

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

蟒蛇3

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


输出:

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

复杂度分析:

  • 时间复杂度: O(1)
  • 空间复杂度: O(1)

注意:此方法只适用于Count way to N’th Stair(Order not matter)的问题。

顺序无关紧要意味着 n = 4 {1 2 1} ,{2 1 1} , {1 1 2}被认为是相同的。

方法5:该方法使用矩阵求幂的技术来得出解决方案。

方法:到达n楼梯(顺序很重要)的方法数等于到达第(n-1)楼梯和第(n-2)楼梯的方法数之和

这对应于以下递推关系:

f(n) = f(n-1) + f(n-2)

f(1) = 1
f(2) = 2

其中 f(n) 表示到达n楼梯的方式数

笔记:

f(1) = 1 因为只有 1 种方法可以到达 n=1 楼梯 {1}

f(2) = 2 因为有 2 种方法可以到达 n=2 楼梯 {1,1} , {2}

它是一种具有常系数的线性递推关系,我们可以使用矩阵求幂方法来解决它们,该方法基本上为给定递推关系找到一个变换矩阵,然后将该变换重复应用于基向量以获得解)。

F(n) = CN-1F(1)
where
C is the transformation matrix
F(1) is the base vector
F(n) is the desired solution

因此,对于我们的情况,变换矩阵 C 将是:

0 1
1 1

C N-1可以使用分而治之技术计算,在 O( (K^3) Log n) 中,其中 K 是 C 的维度

和 F(1):

1
2

例如,对于 n= 4:

F(4) = C 3 F(1)

C 3 =

1 2
2 3

因此,C 3 F(1) =

5
8

C++

#include 
using namespace std;
typedef vector > 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(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 F(3);
    F[1] = 1;
    F[2] = 2;
    int K = 2;
    long long MOD = 1000000007;
    // create K*K matrix
    matrix C(K + 1, vector(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
输出
Number of ways = 5

复杂度分析:

  • 时间复杂度:O(Log n)
  • 空间复杂度:O(1)

问题的概括:

给定一个包含所有有效步骤的数组 A {a1, a2, …., am},计算到达n楼梯的方法数。 (顺序很重要)

例子

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 

方法:

到达第 n 级楼梯的路数由以下递推关系给出

f(n) =  \sum_{i=1}^{i=m} f(n-A_i)

设 K 为 A 中最大的元素。

Step1:计算基向量 F(1)(由 f(1) …. f(K) 组成)

它可以使用动态规划方法在 O(m 2 K) 时间内完成,如下所示:

我们以 A = {2,4,5} 为例。为了计算 F(1) = { f(1), f(2), f(3), f(4), f(5) } 我们将维护一个初始为空的数组并迭代地将 A i附加到它,对于每个A i我们会找到到达 [A i-1 , 到 A i, ] 的方法数 

因此对于 A = {2 ,4 ,5}

设 T 为初始空数组

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)

注意:由于已经计算了一些值(迭代 2 的 1,2 等)我们可以在循环中避免它们

在所有迭代之后,dp 数组将是:[0,1,0,2,1]

因此,A = [2,4,5] 的基向量 F(1) 是:

0
1
0
2
1

现在我们有了基向量 F(1),C(变换矩阵)的计算很容易

第二步:计算C,变换矩阵

它是一个具有元素 A i,i+1 = 1 且最后一行包含常量的矩阵

现在可以通过 A 中该元素的存在来确定常数

因此,对于 A = [2,4,5] 常量将是 c = [1,1,0,1,0](如果 (K-i+1) 存在于 A 中,则 C i = 1,否则为 0,其中 1 <= i <= K )

因此,A =[2,4,5] 的变换矩阵 C 是:

0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
1 1 0 1 0

第 3 步:计算 F(n)

要计算 F(n),使用以下公式:

F(n) = Cn-1F(1)

现在我们有了 C 和 F(1) 我们可以使用分而治之的技术来找到 C n-1 ,从而找到所需的输出

C++

#include 
using namespace std;
typedef vector > 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(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 initialize(vector A)
{
    // Initializes the base vector F(1)
   
    int K = A[A.size() - 1]; // Assuming A is sorted
    vector F(K + 1, 0);
    vector 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 A, int n)
{
    int K = A[A.size() - 1]; // Assuming A is sorted
    vector F = initialize(A); // O(m^2*K)
    int MOD = 1000000007;
    // create K*K matrix
    matrix C(K + 1, vector(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 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
输出
Number of ways = 5

复杂度分析:

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)

笔记:

当 n 对于迭代来说太大时,这种方法是理想的

例如:当 (1 ≤ n ≤ 10 9 ) 和 (1 ≤ m,k ≤ 10 2 ) 时考虑这种方法

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程