(HDOJ)1001——超级楼梯(递推)

来源:互联网 发布:网络打假教程 编辑:程序博客网 时间:2024/06/05 22:08

Problem Description

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

Input

输入数据首先包含一个整数N,表示测试实例的个数,然后是N行数据,每行包含一个整数M(1<=M<=40),表示楼梯的级数。

Output

对于每个测试实例,请输出不同走法的数量

Sample Input

2
2
3

Sample Output

1
2

Author

lcy

Source

2005实验班短学期考试


问题分析

其实这个题是一个动态规划的题,但是用递推也可以很快解决。

这个上台阶的题还是很经典的,假设前面所有的走法全部都得到了,求最后一个f(n)的走法就是f(n-1)+f(n-2),因为f(n)只有这两种情况才能得到,所以就得到了递推公式,所以可以开始编程了。

但是发现调用递归这个没法通过,因为超时了,所以需要对其进行优化,其实递归或者递推求解时候会又很多计算发生重复,所以需要对这些重复的值进行保存。另外设一个数组,将所有计算结果进行保存,优先在数组里面寻找看是否之前已经计算过,否则调用递归重新计算。

AC代码

#include<iostream>#include<algorithm>using namespace std;int a[100];//设置一个保存计算重复的数据int f(int n){    int ans;    if (n == 1)        return 1;    if (n == 2)        return 1;    if (n > 2)//如果N>2需要调用前面的n-1和n-2进行计算    {        if (a[n] != -1){//优先查看是否已经计算过            ans = a[n];        }        else{//否则递归            ans = f(n - 1) + f(n - 2);            a[n] = ans;//记得将这个递归计算的结果写入到以n为下标的数组,其他递推可以在计算时候直接调用这个值        }    }    return ans;}int main(){    int n,m;    cin >> n;    for (int i = 0; i < 100; i++)        a[i] = -1;//将数组置为-1    for (int i = 0; i < n; i++){        cin >> m;        cout << f(m)<<endl;    }    return 0;}