给定一个距离 ‘dist,计算用 1、2 和 3 步覆盖该距离的方法总数。
例子:
Input: n = 3
Output: 4
Explanation:
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
Explanation:
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 是起始位置。 - 算法:
- 创建一个递归函数( count(int n) ),它只接受一个参数。
- 检查基本情况。如果 n 的值小于 0,则返回 0,如果 n 的值等于 0,则返回 1,因为它是起始位置。
- 使用值 n-1、n-2 和 n-3 递归调用该函数并对返回的值求和,即sum = count(n-1) + count(n-2) + count(n-3) 。
- 返回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
C++
// A Dynamic Programming based C++ program to count number of ways
#include
using namespace std;
int printCountDP(int dist)
{
//Create the array of size 3.
int ways[3] , n = dist;
//Initialize the bases cases
ways[0] = 1;
ways[1] = 1;
ways[2] = 2;
//Run a loop from 3 to n
//Bottom up approach to fill the array
for(int i=3 ;i<=n ;i++)
ways[i%3] = ways[(i-1)%3] + ways[(i-2)%3] + ways[(i-3)%3];
return ways[n%3];
}
// driver program
int main()
{
int dist = 4;
cout << printCountDP(dist);
return 0;
}
Java
// A Dynamic Programming based Java program to count number of ways
import java.util.*;
class GFG {
static int printCountDP(int dist)
{
// Create the array of size 3.
int []ways = new int[3];
int n = dist;
// Initialize the bases cases
ways[0] = 1;
ways[1] = 1;
ways[2] = 2;
// Run a loop from 3 to n
// Bottom up approach to fill the array
for(int i=3 ;i<=n ;i++)
ways[i%3] = ways[(i-1)%3] + ways[(i-2)%3] + ways[(i-3)%3];
return ways[n%3];
}
// driver program
public static void main(String arg[])
{
int dist = 4;
System.out.print(printCountDP(dist));
}
}
// this code is contributed by shivanisinghss2110
Python3
# A Dynamic Programming based C++ program to count number of ways
def prCountDP( dist):
# Create the array of size 3.
ways = [0]*3
n = dist
# Initialize the bases cases
ways[0] = 1
ways[1] = 1
ways[2] = 2
# Run a loop from 3 to n
# Bottom up approach to fill the array
for i in range(3, n + 1):
ways[i % 3] = ways[(i - 1) % 3] + ways[(i - 2) % 3] + ways[(i - 3) % 3]
return ways[n % 3]
# driver program
dist = 4
print(prCountDP(dist))
# This code is contributed by shivanisinghss2110
C#
// A Dynamic Programming based C#
// program to count number of ways
using System;
class GFG{
static int printCountDP(int dist)
{
// Create the array of size 3.
int []ways = new int[3];
int n = dist;
// Initialize the bases cases
ways[0] = 1;
ways[1] = 1;
ways[2] = 2;
// Run a loop from 3 to n
// Bottom up approach to fill the array
for(int i = 3; i <= n; i++)
ways[i % 3] = ways[(i - 1) % 3] +
ways[(i - 2) % 3] +
ways[(i - 3) % 3];
return ways[n % 3];
}
// Driver code
public static void Main(String []arg)
{
int dist = 4;
Console.Write(printCountDP(dist));
}
}
// This code is contributed by shivanisinghss2110
Javascript
输出:
7
- 复杂度分析:
- 时间复杂度: O(3 n )。
上述解决方案的时间复杂度是指数级的,接近的上限是 O(3 n )。从每个状态 3 调用一个递归函数。所以 n 个状态的上限是 O(3 n )。 - 空间复杂度: O(1)。
不需要额外的空间。
- 时间复杂度: O(3 n )。
高效的解决方案
- 做法:思路类似,但是可以观察到有n个状态但是递归函数被调用了3^n次。这意味着某些状态会被重复调用。所以这个想法是存储状态的值。这可以通过两种方式完成。
- 第一种方法是保持递归结构完整,只将值存储在 HashMap 中,每当调用函数,不计算就返回值存储(自上而下方法)。
- 第二种方式是取一个额外的n大小的空间,开始计算从1, 2 ..到n的状态值,即计算i, i+1, i+2的值,然后用它们来计算i的值+3(自下而上的方法)。
- 动态规划中的重叠子问题。
- 动态规划中的最优子结构属性。
- 动态规划(DP)问题
- 算法:
- 创建一个大小为 n + 1 的数组,并用 1、1、2 初始化前 3 个变量。基本情况。
- 运行从 3 到 n 的循环。
- 对于每个索引 i,将第 i 个位置的值计算为dp[i] = dp[i-1] + dp[i-2] + dp[i-3] 。
- 打印 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
蟒蛇3
# 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(n)。
只需要遍历一次数组。所以时间复杂度是 O(n) - 空间复杂度: O(n)。
将值存储在 DP O(n) 中需要额外的空间。
- 时间复杂度: O(n)。
更优的解决方案
方法:代替使用大小为 n+1 的数组,我们可以使用大小为 3 的数组,因为为了计算特定步骤的方法数,我们只需要最后 3 步方法数。
算法:
- 创建一个大小为 3 的数组并将步骤 0、1、2 的值初始化为 1、1、2(基本情况)。
- 运行从 3 到 n(dist) 的循环。
- 对于每个索引,将值计算为 way[i%3] = way[(i-1)%3] + way[(i-2)%3] + way[(i-3)%3] 并存储其值在数组方式的 i%3 索引处。如果我们计算索引 3 的值,则计算值将位于索引 0,因为对于较大的索引(4 ,5,6…..),我们不需要索引 0 的值。
- 返回 way[n%3] 的值。
C++
// A Dynamic Programming based C++ program to count number of ways
#include
using namespace std;
int printCountDP(int dist)
{
//Create the array of size 3.
int ways[3] , n = dist;
//Initialize the bases cases
ways[0] = 1;
ways[1] = 1;
ways[2] = 2;
//Run a loop from 3 to n
//Bottom up approach to fill the array
for(int i=3 ;i<=n ;i++)
ways[i%3] = ways[(i-1)%3] + ways[(i-2)%3] + ways[(i-3)%3];
return ways[n%3];
}
// driver program
int main()
{
int dist = 4;
cout << printCountDP(dist);
return 0;
}
Java
// A Dynamic Programming based Java program to count number of ways
import java.util.*;
class GFG {
static int printCountDP(int dist)
{
// Create the array of size 3.
int []ways = new int[3];
int n = dist;
// Initialize the bases cases
ways[0] = 1;
ways[1] = 1;
ways[2] = 2;
// Run a loop from 3 to n
// Bottom up approach to fill the array
for(int i=3 ;i<=n ;i++)
ways[i%3] = ways[(i-1)%3] + ways[(i-2)%3] + ways[(i-3)%3];
return ways[n%3];
}
// driver program
public static void main(String arg[])
{
int dist = 4;
System.out.print(printCountDP(dist));
}
}
// this code is contributed by shivanisinghss2110
蟒蛇3
# A Dynamic Programming based C++ program to count number of ways
def prCountDP( dist):
# Create the array of size 3.
ways = [0]*3
n = dist
# Initialize the bases cases
ways[0] = 1
ways[1] = 1
ways[2] = 2
# Run a loop from 3 to n
# Bottom up approach to fill the array
for i in range(3, n + 1):
ways[i % 3] = ways[(i - 1) % 3] + ways[(i - 2) % 3] + ways[(i - 3) % 3]
return ways[n % 3]
# driver program
dist = 4
print(prCountDP(dist))
# This code is contributed by shivanisinghss2110
C#
// A Dynamic Programming based C#
// program to count number of ways
using System;
class GFG{
static int printCountDP(int dist)
{
// Create the array of size 3.
int []ways = new int[3];
int n = dist;
// Initialize the bases cases
ways[0] = 1;
ways[1] = 1;
ways[2] = 2;
// Run a loop from 3 to n
// Bottom up approach to fill the array
for(int i = 3; i <= n; i++)
ways[i % 3] = ways[(i - 1) % 3] +
ways[(i - 2) % 3] +
ways[(i - 3) % 3];
return ways[n % 3];
}
// Driver code
public static void Main(String []arg)
{
int dist = 4;
Console.Write(printCountDP(dist));
}
}
// This code is contributed by shivanisinghss2110
Javascript
输出 :
7
时间复杂度:O(n)
空间复杂度:O(1)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。