每日一练 C++ 走楼梯

本题有多种思路可以解决,首先想到的是采用枚举法,求解不定方程i+2j=n的所有解,对于每一组解,利用排列组合的知识计算全部路径。

比如所求的的解为i,j,那么对与这组解,全部的路径数为(i+j)的全排列,除以i和j全排列的乘积

这个思路虽然可行,但是对于n较大时计算很慢,复杂度高,超时。

于是我们采取另外的思路,本题还可以用递归的思想解决,即到达第n层的走法数是由到达第n-1层以及到达第n-2层的走法数决定的,即F(N)=F(N-1)+F(N-2)

由此写出递归函数,但是这种方法同样存在时间复杂度高,无法算出n接近50时候的答案,于是我们尝试对其进行优化。本人想出一种拆分方法:对于在1-n中的整数i,我们可以得到如下等式:

F(N)=F(i)F(N-i)+F(i-1)F(N-i-1)

即可以把一个从0-n层的问题,化为两部分,先到i层,再由i层到n层,而i层到n层(需要走n-i层台阶)与0到n-i层是等效的,即后半部分可化为F(N-i),再考虑到存在直接跳过i层的情况,即在i-1层时选择跳2层,由上面的思路同理可以得到表达式。

在n较大时,我们可以采用这个拆分法,从中间将其拆分开,降低递归的难度。

代码如下:

#include <iostream>
#include <cstdio>
using namespace std;

long long stair(long long n)
{
    if(n==1)return 1;
    else if(n==2)return 2;
    else if(n>2)return stair(n-1)+stair(n-2);
}
int main()
{
    long long n;
    long long answer;
    long long h;
    scanf("%lld",&n);
    if(n<=30){
    answer=stair(n);
    printf("%lld",answer);
    }
    else{
       h=n/2;
       answer=stair(h)*stair(n-h)+stair(h-1)*stair(n-h-1);
       printf("%lld",answer);
    }
    return 0;
}


 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值