📜  计算覆盖距离的方法数量

📅  最后修改于: 2021-04-29 08:01:41             🧑  作者: Mango

给定距离’dist,计算以1、2和3步覆盖该距离的方法总数。

例子:

Input: n = 3
Output: 4
Explantion:
Below are the four ways
 1 step + 1 step + 1 step
 1 step + 2 step
 2 step + 1 step
 3 step

Input: n = 4
Output: 7
Explantion:
Below are the four ways
 1 step + 1 step + 1 step + 1 step
 1 step + 2 step + 1 step
 2 step + 1 step + 1 step 
 1 step + 1 step + 2 step
 2 step + 2 step
 3 step + 1 step
 1 step + 3 step

递归解决方案

  • 方法:有n个楼梯,允许一个人进行下一步,跳过一个位置或跳过两个位置。因此,有n个职位。这个想法是站在人可以移动i + 1,i + 2,i + 3位置的第i个位置。因此,可以形成递归函数,其中在当前索引i处,该函数以递归方式调用i + 1,i + 2和i + 3位置。
    还有另一种形成递归函数。要到达位置i,一个人必须从i-1,i-2或i-3位置跳跃,其中i是起始位置。
  • 算法:
    1. 创建一个仅包含一个参数的递归函数( count(int n) )。
    2. 检查基本情况。如果n的值小于0,则返回0;如果n的值等于0,则返回1,因为它是起始位置。
    3. 用值n-1,n-2和n-3递归调用函数,并对返回的值求和,即sum = count(n-1)+ count(n-2)+ count(n-3)
    4. 返回sum的值。
  • 执行:
C++
// A naive recursive C++ program to count number of ways to cover
// a distance with 1, 2 and 3 steps
#include
using namespace std;
 
// Returns count of ways to cover 'dist'
int printCountRec(int dist)
{
    // Base cases
    if (dist<0)      return 0;
    if (dist==0)  return 1;
 
    // Recur for all previous 3 and add the results
    return printCountRec(dist-1) +
           printCountRec(dist-2) +
           printCountRec(dist-3);
}
 
// driver program
int main()
{
    int dist = 4;
    cout << printCountRec(dist);
    return 0;
}


Java
// A naive recursive Java program to count number
// of ways to cover a distance with 1, 2 and 3 steps
import java.io.*;
 
class GFG
{
    // Function returns count of ways to cover 'dist'
    static int printCountRec(int dist)
    {
        // Base cases
        if (dist<0)   
            return 0;
        if (dist==0)   
            return 1;
  
        // Recur for all previous 3 and add the results
        return printCountRec(dist-1) +
               printCountRec(dist-2) +
               printCountRec(dist-3);
    }
     
    // driver program
    public static void main (String[] args)
    {
        int dist = 4;
        System.out.println(printCountRec(dist));
    }
}
 
// This code is contributed by Pramod Kumar


Python3
# A naive recursive Python3 program
# to count number of ways to cover
# a distance with 1, 2 and 3 steps
 
# Returns count of ways to
# cover 'dist'
def printCountRec(dist):
     
    # Base cases
    if dist < 0:
        return 0
         
    if dist == 0:
        return 1
 
    # Recur for all previous 3 and      
   # add the results
    return (printCountRec(dist-1) +
            printCountRec(dist-2) +
            printCountRec(dist-3))
 
# Driver code
dist = 4
print(printCountRec(dist))
# This code is contributed by Anant Agarwal.


C#
// A naive recursive C# program to
// count number of ways to cover a
// distance with 1, 2 and 3 steps
using System;
 
class GFG {
     
    // Function returns count of
    // ways to cover 'dist'
    static int printCountRec(int dist)
    {
        // Base cases
        if (dist < 0)
            return 0;
        if (dist == 0)
            return 1;
 
        // Recur for all previous 3
        // and add the results
        return printCountRec(dist - 1) +
               printCountRec(dist - 2) +
               printCountRec(dist - 3);
    }
     
    // Driver Code
    public static void Main ()
    {
        int dist = 4;
        Console.WriteLine(printCountRec(dist));
    }
}
 
// This code is contributed by Sam007.


PHP


Javascript


C++
// A Dynamic Programming based C++ program to count number of ways
// to cover a distance with 1, 2 and 3 steps
#include
using namespace std;
 
int printCountDP(int dist)
{
    int count[dist+1];
 
    // Initialize base values. There is one way to cover 0 and 1
    // distances and two ways to cover 2 distance
     count[0] = 1;
     if(dist >= 1)
            count[1] = 1;
     if(dist >= 2)
              count[2] = 2;
 
    // Fill the count array in bottom up manner
    for (int i=3; i<=dist; i++)
       count[i] = count[i-1] + count[i-2] + count[i-3];
 
    return count[dist];
}
 
// driver program
int main()
{
    int dist = 4;
    cout << printCountDP(dist);
    return 0;
}


Java
// A Dynamic Programming based Java program
// to count number of ways to cover a distance
// with 1, 2 and 3 steps
import java.io.*;
 
class GFG
{
    // Function returns count of ways to cover 'dist'
    static int printCountDP(int dist)
    {
        int[] count = new int[dist+1];
  
        // Initialize base values. There is one way to
        // cover 0 and 1 distances and two ways to
        // cover 2 distance
        count[0] = 1;
          if(dist >= 1)
            count[1] = 1;
        if(dist >= 2)
              count[2] = 2;
  
        // Fill the count array in bottom up manner
        for (int i=3; i<=dist; i++)
            count[i] = count[i-1] + count[i-2] + count[i-3];
  
        return count[dist];
    }
     
    // driver program
    public static void main (String[] args)
    {
        int dist = 4;
        System.out.println(printCountDP(dist));
    }
}
 
// This code is contributed by Pramod Kumar


Python3
# A Dynamic Programming based on Python3
# program to count number of ways to
# cover a distance with 1, 2 and 3 steps
 
def printCountDP(dist):
    count = [0] * (dist + 1)
     
    # Initialize base values. There is
    # one way to cover 0 and 1 distances
    # and two ways to cover 2 distance
    count[0] = 1
    if dist >= 1 :
        count[1] = 1
    if dist >= 2 :
        count[2] = 2
     
    # Fill the count array in bottom
    # up manner
    for i in range(3, dist + 1):
        count[i] = (count[i-1] +
                   count[i-2] + count[i-3])
         
    return count[dist];
 
# driver program
dist = 4;
print( printCountDP(dist))
 
# This code is contributed by Sam007.


C#
// A Dynamic Programming based C# program
// to count number of ways to cover a distance
// with 1, 2 and 3 steps
using System;
 
class GFG {
     
    // Function returns count of ways
    // to cover 'dist'
    static int printCountDP(int dist)
    {
        int[] count = new int[dist + 1];
 
        // Initialize base values. There is one
        // way to cover 0 and 1 distances
        // and two ways to cover 2 distance
        count[0] = 1;
        count[1] = 1;
        count[2] = 2;
 
        // Fill the count array
        // in bottom up manner
        for (int i = 3; i <= dist; i++)
            count[i] = count[i - 1] +
                       count[i - 2] +
                       count[i - 3];
 
        return count[dist];
    }
     
    // Driver Code
    public static void Main ()
    {
        int dist = 4;
        Console.WriteLine(printCountDP(dist));
    }
}
 
// This code is contributed by Sam007.


PHP


Javascript


输出:

7
  • 复杂度分析:
    • 时间复杂度: O(3 n )。
      上述解决方案的时间复杂度是指数的,上限接近O(3 n )。从每个状态3调用递归函数。因此,n个状态的上限为O(3 n )。
    • 空间复杂度: O(1)。
      不需要额外的空间。

高效的解决方案

  • 方法:这个想法很相似,但是可以观察到有n个状态,但是递归函数被调用3 ^ n次。这意味着某些状态会被反复调用。因此,想法是存储状态值。这可以通过两种方式完成。
    • 第一种方法是保持递归结构完整,仅将值存储在HashMap中,无论何时调用该函数,都无需计算即可返回值存储(自顶向下方法)。
    • 第二种方法是占用大小为n的额外空间,并开始计算从1、2 ..到n的状态值,即计算i,i + 1,i + 2的值,然后使用它们来计算i的值+3(自下而上的方法)。
    • 动态编程中的子问题重叠。
    • 动态编程中的最佳子结构属性。
    • 动态编程(DP)问题
  • 算法:
    1. 创建一个大小为n + 1的数组,并使用1、1、2(基本情况)初始化前三个变量。
    2. 从3到n运行一个循环。
    3. 对于每个索引i,第i个位置的计算机值分别为dp [i] = dp [i-1] + dp [i-2] + dp [i-3]
    4. 打印dp [n]的值,作为覆盖距离的数量的计数。
  • 执行:

C++

// A Dynamic Programming based C++ program to count number of ways
// to cover a distance with 1, 2 and 3 steps
#include
using namespace std;
 
int printCountDP(int dist)
{
    int count[dist+1];
 
    // Initialize base values. There is one way to cover 0 and 1
    // distances and two ways to cover 2 distance
     count[0] = 1;
     if(dist >= 1)
            count[1] = 1;
     if(dist >= 2)
              count[2] = 2;
 
    // Fill the count array in bottom up manner
    for (int i=3; i<=dist; i++)
       count[i] = count[i-1] + count[i-2] + count[i-3];
 
    return count[dist];
}
 
// driver program
int main()
{
    int dist = 4;
    cout << printCountDP(dist);
    return 0;
}

Java

// A Dynamic Programming based Java program
// to count number of ways to cover a distance
// with 1, 2 and 3 steps
import java.io.*;
 
class GFG
{
    // Function returns count of ways to cover 'dist'
    static int printCountDP(int dist)
    {
        int[] count = new int[dist+1];
  
        // Initialize base values. There is one way to
        // cover 0 and 1 distances and two ways to
        // cover 2 distance
        count[0] = 1;
          if(dist >= 1)
            count[1] = 1;
        if(dist >= 2)
              count[2] = 2;
  
        // Fill the count array in bottom up manner
        for (int i=3; i<=dist; i++)
            count[i] = count[i-1] + count[i-2] + count[i-3];
  
        return count[dist];
    }
     
    // driver program
    public static void main (String[] args)
    {
        int dist = 4;
        System.out.println(printCountDP(dist));
    }
}
 
// This code is contributed by Pramod Kumar

Python3

# A Dynamic Programming based on Python3
# program to count number of ways to
# cover a distance with 1, 2 and 3 steps
 
def printCountDP(dist):
    count = [0] * (dist + 1)
     
    # Initialize base values. There is
    # one way to cover 0 and 1 distances
    # and two ways to cover 2 distance
    count[0] = 1
    if dist >= 1 :
        count[1] = 1
    if dist >= 2 :
        count[2] = 2
     
    # Fill the count array in bottom
    # up manner
    for i in range(3, dist + 1):
        count[i] = (count[i-1] +
                   count[i-2] + count[i-3])
         
    return count[dist];
 
# driver program
dist = 4;
print( printCountDP(dist))
 
# This code is contributed by Sam007.

C#

// A Dynamic Programming based C# program
// to count number of ways to cover a distance
// with 1, 2 and 3 steps
using System;
 
class GFG {
     
    // Function returns count of ways
    // to cover 'dist'
    static int printCountDP(int dist)
    {
        int[] count = new int[dist + 1];
 
        // Initialize base values. There is one
        // way to cover 0 and 1 distances
        // and two ways to cover 2 distance
        count[0] = 1;
        count[1] = 1;
        count[2] = 2;
 
        // Fill the count array
        // in bottom up manner
        for (int i = 3; i <= dist; i++)
            count[i] = count[i - 1] +
                       count[i - 2] +
                       count[i - 3];
 
        return count[dist];
    }
     
    // Driver Code
    public static void Main ()
    {
        int dist = 4;
        Console.WriteLine(printCountDP(dist));
    }
}
 
// This code is contributed by Sam007.

的PHP


Java脚本


输出 :

7
  • 复杂度分析:
    • 时间复杂度: O(n)。
      只需要遍历数组一次。所以时间复杂度是O(n)
    • 空间复杂度: O(n)。
      要将值存储在DP O(n)中,需要额外的空间。