金榜题名萱头像

蓝桥杯DP入门——爬楼梯(一次可走1/2/3步)超详细底层推导

题目描述

现一个算法求解台阶问题。介绍如下:

  • 对于高度为 nn 的台阶,从下往上走,每一步的阶数为 1,2,3 中的一个。问要走到顶部一共有多少种走法。

输入描述

输入一个数字 N (1≤N≤35)N (1≤N≤35),表示台阶的高度。

输出描述

输出一行,为走法总数。

输入输出样例

输入

4

输出

7

解题思路

一、最核心的底层逻辑(全部看懂靠这个)


动态规划永远只思考 最后一步
DP万能思维:
&到达第 n 级台阶的所有方法 = 所有能一步走到 n 的位置的方案总和
 
本题规则:最后一步只能是三种情况
1. 最后走1步 → 说明我之前站在  n-1 
2. 最后走2步 → 说明我之前站在  n-2 
3. 最后走3步 → 说明我之前站在  n-3 
 
所以公式直接推导出来:
dp[n] = dp[n-1] + dp[n-2] + dp[n-3]

二、手动枚举,彻底搞懂初始值


n = 1
只有 1 种:
1 →  dp[1] = 1 
 
n = 2
两种走法:
1+1 -> 2  dp[2] = 2 
 
n = 3(重点,为什么是4,彻底讲透)
全部列出来:
1. 1 + 1 + 1
2. 1 + 2
3. 2 + 1
4. 3
一共 4种 -> dp[3] = 4 
 
关键理解:
 1+2  和  2+1  顺序不一样,是两种完全不同的走路方式,不能合并

三、完整解题思路总结


1. dp[i] 定义:走到第 i 级台阶的总方案数
2. 最后一步只有 1、2、3步三种可能
3. 递推式: dp[i] = dp[i-1] + dp[i-2] + dp[i-3] 
4. 初始化前3项:1、2、4
5. 循环从4推到n
6. 结果较大,必须用 long long 防溢出

完整代码

#include <stdio.h>

#include <stdlib.h>

int main(int argc, char *argv[])

{

  int n;

  long long dp[100];

  scanf("%d",&n);

  dp[1]=1;//从0到1,一步

  dp[2]=2;//(1)从1到2 (2)从0到2 

  dp[3]=4;//(1)走一步:1+1+1 (2)1+2 (3)2+1 (4) 3步到

  int i;

  for(i=4;i<=n;i++)

  {

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

  }

  printf("%lld\n",dp[n]);

  return 0;

}

踩坑记录


1. 最大误区:认为 n=3 是3种
忽略顺序不同算不同方案,1+2 和 2+1 是两种走法,所以是4种。
2. 容易和普通爬楼梯混淆
普通只能走1、2步: dp[i] = dp[i-1] + dp[i-2] ,本题能走3步,必须多加一项 dp[i-3]
3. 数据溢出问题
n到30+之后数字非常大,int存不下,必须用 long long
4. DP本质理解误区
DP不是暴力枚举所有路线
是利用前面算好的结果,累加最后一步的所有可能性。

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/2402_87421821/article/details/169950759

文章来源转载

评论

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--