本题有多种思路可以解决,首先想到的是采用枚举法,求解不定方程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;
}