三步问题

解法(动态规划)

算法思路

1. 状态表⽰ 

dp[i] 表⽰:到达 i 位置时,⼀共有多少种⽅法。

2. 状态转移⽅程

以 i 位置状态的最近的⼀步,来分情况讨论: 如果 dp[i] 表⽰⼩孩上第 i 阶楼梯的所有⽅式,那么它应该等于所有上⼀步的⽅式之和:

i. 上⼀步上⼀级台阶, dp[i] += dp[i - 1] ;

ii. 上⼀步上两级台阶, dp[i] += dp[i - 2] ;

iii. 上⼀步上三级台阶, dp[i] += dp[i - 3] ;

综上所述, dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3] 。 需要注意的是,这道题⽬说,由于结果可能很⼤,需要对结果取模。 在计算的时候,三个值全部加起来再取模,即 (dp[i - 1] + dp[i - 2] + dp[i - 3]) % MOD 是不可取的, n 取题⽬范围内最⼤值时 。 对于这类需要取模的问题,我们每计算⼀次(两个数相加/乘等),都需要取⼀次模。如果溢出,我们的答案就错了。

3. 初始化

从我们的递推公式可以看出, dp[i] 在 i = 0, i = 1 以及 i = 2 的时候是没有办法进⾏ 推导的,因为 dp[-3] dp[-2] 或 dp[-1] 不是⼀个有效的数据。 因此我们需要在填表之前,将 1, 2, 3 位置的值初始化。 根据题意, dp[1] = 1, dp[2] = 2, dp[3] = 4 。

4. 填表顺序:

从左往右。

5. 返回值

应该返回 dp[n] 的值。

class Solution 
{
public:
    int waysToStep(int n) 
    {
        // 创建表
        vector<int> dp(n + 1);
        // 处理边界
        if (n == 1 || n == 2)
            return n;

        // 初始化
        dp[1] = 1, dp[2] = 2, dp[3] = 4;
        // 从左往右填表
        for (int i = 4; i <= n; i++)
            dp[i] = ((long long)(dp[i-1]) + dp[i - 2] + dp[i-3]) % 1000000007;
        
        return dp[n];
    }
};

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值