爬楼梯问题总结 (递推)

超级楼梯

链接:

http://acm.hdu.edu.cn/showproblem.php?pid=2041

题意:

有一楼梯共M级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第M级,共有多少种走法?

分析:

首先题目限制只能走一级或者两级, 所以逆向思考一下, 要到达n级楼梯, 只有两种方式,从(n-1)级 或 (n-2)级到达的。

所以可以用递推的思想去想这题,假设有一个数组s[n], 那么s[1] = 1(由于一开始就在第一级,只有一种方法), s[2] = 1(只能从s[1]上去 没有其他方法)。

那么就可以推出s[3] ~ s[n]了。

下面继续模拟一下, s[3] = s[1] + s[2], 因为只能从第一级跨两步, 或者第二级跨一步。

如果是第一级跨一步再跨一步, 就等于第二步跨一步,这就重复了。(因为每一级都是相差1, 所以不能有从哪一级跨出一步这种走法, 除了跨出一级就到达目的地)。

frog

链接:

http://acm.dhu.edu.cn/contest/view.html?id=873&index=2

题意:

这题可以说是上一题的加强版,可以看成有M级楼梯,刚开始你在0级(平地), 每次能跨L步,共有多少种走法。

分析:

这题可以类比上一题, 如果上一题只能走两步的话,走上n级考虑(n-1)和(n-2),那么这题可以看成走上n级考虑(n-1),(n-2)...(n-L)级。

那么同理 s[0] = 1; s[1] = 1;

然后s[2]~s[L]就可以推了(因为这一部分的前面都不足n级,特殊考虑)

for 2~L ← i

  s[i] = sum(s[0],s[i])

然后s[L+1]到s[n]的部分可以(这一部分前面肯定有n级, 一般情况)

for L+1 ~ n ← i

  s[i] = sum(s[i-1 - L],s[i-1])  //总长为L的楼梯的方法数之和

最后输出s[n]即可。

该题需要 % 1e9+7, 注意同余的特性:

(a+b) mod n = (a mod n + b mod n) mod n

(a-b) mod n = (a mod n - b mod n + n) mod n (因为a mod n 可能小于 b mod n  所以需要加上一个n)

#include<bits/stdc++.h>
using namespace std;
int n , l;
const int maxn = 100005;
const long long mod = 1e9 + 7;
long long dp[maxn];
int main()
{
    while(~scanf("%d %d", &n, &l))
    {
        if(l == 1)
        {
            printf("1\n");
            continue;
        }
        dp[0] = dp[1] = 1;
        int t = dp[0] + dp[1];
        for(int i = 2; i <= l; i ++)
        {
            dp[i] = t;
            t += dp[i];
            t %= mod;
        }
        for(int i = l+1; i <= n; i++)
        {
            dp[i] =((2*dp[i-1])%mod - (dp[i-1-l]%mod) + mod) % mod;
            //这部分可以推一下, 如 L = 2时,
            //     dp[4] = dp[3] + dp [2];
            //那么 dp[5] = dp[4] + dp[3] = dp[4] + dp[4] - dp[2] = 2*dp[4] - dp[2];
        }
        printf("%lld\n", dp[n]);
    }
}
时间: 2024-11-05 22:06:00

爬楼梯问题总结 (递推)的相关文章

LeetCode 70 - 爬楼梯 - [递推+滚动优化]

假设你正在爬楼梯.需要 n 阶你才能到达楼顶. 每次你可以爬 1 或 2 个台阶.你有多少种不同的方法可以爬到楼顶呢? 注意:给定 n 是一个正整数. 示例 1: 输入: 2输出: 2解释: 有两种方法可以爬到楼顶.1. 1 阶 + 1 阶2. 2 阶 示例 2: 输入: 3输出: 3解释: 有三种方法可以爬到楼顶.1. 1 阶 + 1 阶 + 1 阶2. 1 阶 + 2 阶3. 2 阶 + 1 阶 设 $f[n]$ 表示跳上 $n$ 级台阶的方案数目,因此很容易得到 $f[n] = f[n-1

(hdu step 3.1.1)超级楼梯(简单递推:从第1级到第m级有多少种走法,每次只能走一步或两步)

在写题解之前给自己打一下广告哈~..抱歉了,希望大家多多支持我在CSDN的视频课程,地址如下: http://edu.csdn.net/course/detail/209 题目: 超级楼梯 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 652 Accepted Submission(s): 483   Problem Description

3089:爬楼梯

总时间限制: 1000ms 内存限制: 65536kB描述树老师爬楼梯,他可以每次走1级或者2级,输入楼梯的级数,求不同的走法数例如:楼梯一共有3级,他可以每次都走一级,或者第一次走一级,第二次走两级也可以第一次走两级,第二次走一级,一共3种方法. 输入输入包含若干行,每行包含一个正整数N,代表楼梯级数,1 <= N <= 30输出不同的走法数,每一行输入对应一行输出样例输入5810样例输出83489 算法:递归或递推,模型:斐波那契数列. 1 #include <stdio.h>

一堆递推题

目录 一堆递推题 P1367[训练题]爬楼梯[2] 描述 輸入 輸出 輸入範例 1 輸出範例 1 提示 思路 铺瓷砖 描述 輸入 輸出 輸入範例 1 輸出範例 1 思路 城市路径 描述 輸入 輸出 輸入範例 1 輸出範例 1 提示 思路 彩带 描述 輸入 輸出 輸入範例 1 輸出範例 1 提示 思路 斐波那契前N项和 描述 輸入 輸出 輸入範例 1 輸出範例 1 提示 思路 偶数个3 描述 輸入 輸出 輸入範例 1 輸出範例 1 思路 回文拆分 描述 輸入 輸出 輸入範例 1 輸出範例 1 思路

动态规划-爬楼梯问题

其实我一直分不清楚动态规划和分治,递归之间的区别与联系...<( ̄3 ̄)> 三者之间应该是有点关系的吧 网上说: 1. 什么是动态规划?         和分治法一样,动态规划(dynamicprogramming)是通过组合子问题而解决整个问题的解.         分治法是将问题划分成一些独立的子问题,递归地求解各子问题,然后合并子问题的解.         动态规划适用于子问题不是独立的情况,也就是各子问题包含公共的子子问题.         此时,分治法会做许多不必要的工作,即重复地求

递推-练习2--noi3525:上台阶

递推-练习2--noi3525:上台阶 一.心得 二.题目 3525:上台阶 总时间限制:  1000ms 内存限制:  65536kB 描述 楼梯有n(100 > n > 0)阶台阶,上楼时可以一步上1阶,也可以一步上2阶,也可以一步上3阶,编程计算共有多少种不同的走法. 输入 输入的每一行包括一组测试数据,即为台阶数n.最后一行为0,表示测试结束. 输出 每一行输出对应一行输入的结果,即为走法的数目. 样例输入 1 2 3 4 0 样例输出 1 2 4 7 三.AC代码 1 #includ

从一道NOI练习题说递推和递归

一.递推: 所谓递推,简单理解就是推导数列的通项公式.先举一个简单的例子(另一个NOI练习题,但不是这次要解的问题): 楼梯有n(100 > n > 0)阶台阶,上楼时可以一步上1阶,也可以一步上2阶,也可以一步上3阶,编程计算共有多少种不同的走法. 这个问题可以用递归来进行解决,但是解题时间1秒明显不够用.怎么办呢,可以考虑找到“规律”,然后推导公式解决问题,开始画图分析: 这是4个台阶时的全部7种走法,记作f(4)=7.现在观察右侧绿色走过的部分,1234四种情况是3个台阶时的4种走,法记

算法之动态规划(递推求解一)

这篇博客主要讲的是动态规划入门,即动态规划的思想,并且再讲解动态规划的最简单的一个方法. 首先,什么是动态规划? 动态规划是通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推(或者说分治)的方式去解决.其实就是分解问题,分而治之.可能这样说大家都不太理解,其实这个有点类似于数学中的递推公式.来举一个简单的例子,看下边这个题: N阶楼梯上楼问题:一次可以走两阶或一阶,问有多少种上楼方式. 这就是动态规划就简单的一个列子.拿到这个题,大家是不是都有点迷,这个到底怎么做?是不是没有思路,那

递推DP URAL 1017 Staircases

题目传送门 1 /* 2 题意:给n块砖头,问能组成多少个楼梯,楼梯至少两层,且每层至少一块砖头,层与层之间数目不能相等! 3 递推DP:dp[i][j] 表示总共i块砖头,最后一列的砖头数是j块的方案数 4 状态转移方程:dp[i][j] += dp[i-j][k] 表示最后一列是j,那么上一个状态是少了最后一列 5 总共i-j块砖头,倒数第二列是k块砖头.k<j, j<=i 6 最后累加dp[n][i], i<n因为最少要两层 7 dp[0][0] = 1; 8 还有更简单的做法,没