爬楼梯(动态规划)

假设你正在爬楼梯。需要 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 阶c

初解(动态规划): 

class Solution {
public:
    int climbStairs(int n) {
        // 处理边界情况:当台阶数为1或2时,直接返回结果
        if(n == 1) return 1;  // 只有1种爬法:一步
        if(n == 2) return 2;  // 有2种爬法:一步一步或直接两步
        
        // 创建动态规划数组dp,dp[i]表示爬到第i+1阶台阶的方法数
        // 注意:由于索引从0开始,dp[i]对应第i+1阶台阶(例如dp[0]对应第1阶)
        vector dp(n);
        
        // 初始化基础情况:
        dp[0] = 1;  // 第1阶台阶只有1种爬法
        dp[1] = 2;  // 第2阶台阶有2种爬法
        
        // 从第3阶开始递推:每阶的方法数等于前两阶的方法数之和
        for(int i = 2; i < n; i++) {
            // 状态转移方程:dp[i] = dp[i-1] + dp[i-2]
            // 解释:到达第i+1阶台阶的方法数 = 到达第i阶的方法数(再爬一步) + 到达第i-1阶的方法数(再爬两步)
            dp[i] = dp[i-1] + dp[i-2];
        }
        
        // 返回第n阶台阶的方法数(注意索引为n-1)
        return dp[n-1];
    }
};

优化(滚动数组): 

int climbStairs(int n) {
    // 处理边界情况:当台阶数为1或2时,直接返回n(1阶有1种,2阶有2种)
    if(n <= 2) return n;
    
    // 初始化前两个状态:a表示第i-2阶的方法数,b表示第i-1阶的方法数
    int a = 1, b = 2, c;
    
    // 从第3阶开始循环,逐步计算到第n阶
    for(int i = 3; i <= n; i++) {
        // 计算当前阶的方法数:等于前两阶的方法数之和
        c = a + b;
        
        // 滚动更新状态:a移动到b的位置,b移动到c的位置
        a = b;  // a变为b(即第i-1阶变为新的第i-2阶)
        b = c;  // b变为c(即当前阶变为新的第i-1阶)
    }
    
    // 循环结束时,b存储的是第n阶的方法数
    return b;
}

(要掌握)

1、dp数组及下标含义

2、打印dp数组(检查)

 

 解动态规划一般步骤:

1、求递推

2、dp数组初始化

3、遍历顺序

你可能感兴趣的:(算法)