• 代码随想录笔记_动态规划_70爬楼梯


    代码随想录二刷笔记记录

    LC70.爬楼梯


    题目

    完全背包

    假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

    每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

    示例 1:

    输入:n = 2
    输出:2
    解释:有两种方法可以爬到楼顶。

    1. 1 阶 + 1 阶
    2. 2 阶

    示例2:

    输入:n = 3
    输出:3
    解释:有三种方法可以爬到楼顶。

    1. 1 阶 + 1 阶 + 1 阶
    2. 1 阶 + 2 阶
    3. 2 阶 + 1 阶

    提示:

    1 <= n <= 45


    思路分析1

    方法1:归纳

    动态规划五部曲

    1.确定dp数组和下标意义

    dp[i] 的定义:  i 个数代表爬到第 i 层有 dp[i] 个方案
    
    • 1

    2.确定递推公式

    要爬 n 阶楼梯,

    设我们在第 n-1 层台阶时,有dp[n-1]个方案,再爬1个台阶就抵达楼顶.

    在第 n-2 步时,有dp[n-2]个方案,再爬 2 个台阶就抵达楼顶。

    设求爬 n 阶楼梯的函数为 f ,则有

    f(n) = f(n-1) + f(n-2)
    
    dp[i] = dp[i-1] + dp[i-2]
    
    
    • 1
    • 2
    • 3
    • 4

    3.dp数组初始化

    依题意,最少要2个台阶,因此第0层没有方法 -> dp[0] = 0 (这里无论dp[0] = 多少,都是没有意义的,因为遍历从dp[2]开始,所以 dp[0] 无论等于1 还是 0 都无所谓)

    第1层有 1 种方法,就是一个台阶 dp[1] = 1,

    第2层有 2 种方法,1+1 和 2 ,因此 dp[2] = 2

    4.确定遍历顺序

    由递推公式 dp[i] = dp[i-1] + dp[i-2] 可知, 第 i 层阶梯的方案要依赖于第 i-1 层有dp[i-1]个方案和第 i-2 层有 dp[i-2] 个方案,因此是从前往后遍历。

    5.推演分析

    以 n = 6 为例

    dp[3] = 3, dp[4] = 5 ,dp[5] = 8,dp[6] = 13


    代码实现1

    完整代码实现

    public int climbStairs(int n) {
    		//特判
            if (n <= 2) return n;
            //初始化
            int[] dp = new int[2];
            dp[1] = 1;
            dp[2] = 2;
            int method = 0;
            //遍历
            for (int i = 3;i <= n;i++){
                method = dp[i-1] + dp[i-2];
                dp[i-2] = dp[i-1];
                dp[i-1] = method;
            }
            return method;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    思路分析2

    方法2:动态规划_完全背包

    以完全背包的方法解答 70 题

    由题,分析可知: 物品为 一阶台阶,二阶台阶。背包容量:爬到楼顶的层数

    台阶可以重复取,因此本题是一个完全背包问题。

    动态规划五部曲

    1.确定dp数组及其下标含义

    dp[j]: 爬到 j 层的楼, dp[j] 种方法
    
    • 1

    2.递推公式

    由 LC494,377,518 可知,回顾求装满背包共有几种方法的递推公式

    dp[j] += dp[j - nums[i]]
    
    • 1

    而本题,求第 j 层台阶的方法dp[j] , 由之前的dp[j-1],dp[j-2],… 推导而来

    因此,递推公式为

    dp[j] += dp[j-i]
    
    • 1

    3.初始化

    dp[0] = 1,和之前的题目LC494,377,518一样,第一项需要初始化为1,否则会影响后续的推导。

    4.遍历顺序

    由示例2可知,1阶 + 2阶 和 2阶 + 1阶 不同,因此可以确定,本题所求的答案是各种排列的总数。求排列,我们采用的遍历顺序为先遍历背包,后遍历物品

    for(i = 0;i <= n;i++){ //背包
    	for(j = 1;j <= 2;j++){//物品
    		if(i >= j){ //当背包容量 >= 物品时,计算才有意义
    			dp[i] += dp[i - j];
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    5.推演分析

    以 n = 3 为例

    请添加图片描述


    代码实现2

    public int climbStairs(int n) {
            if (n <= 2) return n;
        	//初始化
            int[] dp = new int[n + 1];
            dp[0] = 1;
        //先遍历背包,后遍历物品
            for (int i = 0; i <= n; i++) { //背包
                for (int j = 1; j <= 2; j++) { //物品
                    //背包容量 > 物品时,才开始更新
                    if (i >= j){
                        dp[i] += dp[i - j];
                    }
                }
            }
            return dp[n];
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    总结

    针对本题的完全背包用法,进行一个回顾
    1.递推公式
    针对组合问题,我们一般采用的公式都是

    dp[i] += dp[j - nums[i]]
    
    • 1

    2.遍历顺序
    组合问题我们还需要考虑遍历顺序的问题,根据题目给出的示例,我们可以判断,如:(1,2) 和 (2,1) 是否是同一个答案。是,则代表题目考虑的是组合问题;否,则代表我们所求的是排列问题。

    • 组合问题:先遍历物品,后遍历背包
    • 排列问题:先遍历背包,后遍历物品

    小拓展

    一步一个台阶,两个台阶,三个台阶,直到 m个台阶,有多少种方法走到 n 阶楼顶。

    代码实现

    public int climbStairs(int n) {
            int[] dp = new int[n+1];
            dp[0] = 1;
            for (int i = 1;i <= n;i++){
            	for(int j = 1; j<= m; j++){
            	//m表示最多可以爬m个台阶
            		if(i - j >= 0) dp[i] += dp[i-j];
            	}
            }
            return dp[n];
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 相关阅读:
    DHCP执行流程详解
    ES6知识点总结——学习网站及环境搭建
    YB4554是一款经济高效、完全集成的高端输入电压单电池锂离子电池充电器。
    Android---打开相机拍照
    stm32——hal库学习笔记(定时器)
    波束形成,通过matlab仿真不同参数的波束形成以及旁絆级
    全网最新~使用Shell脚本搭建双机高可用的Lustre集群
    推荐系统中的特征工程
    docker-compose搭建私有Gitlab
    【FreeCodeCamp】 ResponsiveWebDesign网页设计 测试1学习笔记
  • 原文地址:https://blog.csdn.net/Erik_Ying/article/details/126173587