[c++思路+ code] 台阶问题

台阶问题一直是动态规划的经典题目,今天给大家两种台阶问题

台阶问题一:步数上限为2

        思路 :这种题一看就不好推理,那么我们不妨从样例下手。

                    样例一:一共爬2级,一共两种情况

                    样例二:一共爬3级,一共3种情况

                这道题我们在上面提到过,是动态规划(dp)的经典题目,那么,这道题的递推公式是最重要的。

                    我们发现

                        

   '''
        n = 1 1
        n = 2 2
        n = 3 1+2
        n = 4 2+3
        n = 5 3+4
        '''

                也就是说: 爬n级台阶的总方案数其实是n-1级台阶的总方案数 + n-2级台阶的总方案数

        那么递推公式就是dp[i] = dp[i-1] + dp[i-2]; 

               那么,这道题的代码也就出来了

           代码:

                        

class Solution {
public:
    int climbStairs(int n) {
        vector<int> f(n + 1);
        f[0] = f[1] = 1;
        for (int i = 2; i <= n; i++) {
            f[i] = f[i - 1] + f[i - 2];
        }
        return f[n];
    }
};

 

台阶问题二:步数上限为三

        这种题和上面的题一样,

 

  • 设 dp[i]表示到达第i  阶楼梯的方式数。
  • 初始条件:
  • dp[0]=1:表示到达第 0 阶的方式数为 1(即不爬楼梯)。
  • dp[1]=1:只有一种方式(走 1 阶)。
  • dp[2]=2:有两种方式(1+1或2)。
        • 状态转移方程:
        • 小孩可以从第i−1阶走 i阶。
        • 小孩可以从第i−2 阶走 2阶到第 i阶。
        • 小孩可以从第 i−3阶走 3阶到第 i 阶。
        • 因此,状态转移方程为:dp[i] = dp[i-1] + dp[i-2] + dp[i-3]

            代码:

                

        class Solution {
            const int MOD = 1e9 + 7;
        public:
            int waysToStep(int n) {
                if (n == 0) return 1;
                if (n == 1) return 1;
                if (n == 2) return 2;
        
                vector<long long> dp(n + 1, 0);
                dp[0] = 1;
                dp[1] = 1;
                dp[2] = 2;
        
                for (int i = 3; i <= n; ++i) {
                    dp[i] = (dp[i - 1] + dp[i - 2] + dp[i - 3]) % MOD;
                }
        
                return dp[n];
            }
        };
        
        

        那么以上就是两种爬楼梯问题了,那么最后的最后,我们总结一下递推公式应该是 (n = 步数上限)

                                dp[i] = dp[i-1] + dp[i-2] + dp[i-3] + ..... + dp[i-n](n = Maximum number of steps)

           

          好了,今天的博客就到这里了,我是calmyself,我们下篇博客再见! 

          评论
          添加红包

          请填写红包祝福语或标题

          红包个数最小为10个

          红包金额最低5元

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

          抵扣说明:

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

          余额充值