*HDoj 2041 超级楼梯

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

 

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

 

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

 

Sample Input
2 2 3
 

 

Sample Output
1 2
 

 

Author
lcy
 

 

Source
 

 

Recommend
lcy   |   We have carefully selected several similar problems for you:  2044 2045 2046 2050 2042 
 
 
 
采用递归,要注意判断分支条件,否则可能会出现无休止的嵌套
注意答案对但是超时了:
#include<stdio.h>
int s=0;
void up(int start,int m)
{
    if(start==m)
        s++;
    else if(start<m)      //如果这里不加判断,可能走到的楼梯数已经超过了m,此时就是无休止的进入else,无休止的递归
    {
        up(start+1,m);
        up(start+2,m);
    }
}

int main()
{
    int n,m;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        s=0;
        scanf("%d",&m);
        up(1,m);
        printf("%d\n",s);
    }
}

 

 

正确解法:

使用动态规划思想,这个问题可以被分解为一些包含最优子结构的子问题,即它的最优解可以从其子问题的最优解来有效地构建,我们可以使用动态规划来解决这一问题。

第 i 阶要么是从第 i-1 阶爬一阶上来,

要么从第 i-2 阶爬两阶上来

即爬到第 i 阶的走法数 dp[i] = dp[i-1] + dp[i-2] 

由此不断循环,即可得出答案。

C语言代码如下:

#include<stdio.h>
#include<malloc.h>
int main()
{
    int n,m;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d",&m);
        int *dp=(int *)malloc(sizeof(int)*(m+1));
        dp[1]=1;           //走到第一阶的方法只有一个(也就是一步也不走)
        dp[2]=1;           //走到第二阶的方法只有一个(只能从第一阶爬一阶)
        for(int i=3;i<=m;i++)
            dp[i]=dp[i-1]+dp[i-2];        //第 i 阶的走法数等于第 i-1 阶走法数和第 i-2 阶走法数之和
        printf("%d\n",dp[m]);
    }
}

 

posted on 2020-03-31 22:57  沈香茶  阅读(242)  评论(0)    收藏  举报