问题1:楼梯上有n阶台阶,上楼时可以一步上1阶,也可以一步上两阶,编写算法计算共有多少种不同的上楼梯的方法。
为什么说上楼梯问题是斐波那契数列的应用呢?我们可以先列举n比较小的时候。
n=1:只有 {1} 一种(1)
n=2:可以有 {1 1} 和2 两种(2)
n=3:可以有 {1 2} 和 {2 1} 和{1 1 1} 三种(3)
n=4:可以有{2 2} 和{1 1 2} 和{1 2 1} 和{2 1 1}和 {1 1 1 1} 五种(5)
…
而斐波那契数列(Fibonacci sequence),又称黄金分割数列指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……
所有经过推导可以看出来该问题可用斐波那契数列求解。
以下为斐波那契数列的公式,若要直接用该函数求解楼梯问题在调用时候需要n+1
public static int Fibonacci(int n)
{
if(n==0)
{
return 0;
}
if(n==1)
{
return 1;
}
return Fibonacci(n-1)+Fibonacci(n-2);
}
我们还可以这样理解这个问题,当楼梯数为n时,我们当前需要计算的上楼梯方法可以用当楼梯数为n-1时的上楼梯方法数+楼梯数为n-2时的上楼梯方法数。
public static int Stairs(int n)
{
if(n==1)
{
//楼梯数为1时上楼梯方法为1
return 1;
}
if(n==2)
{
//楼梯数为2时上楼梯方法为2
return 2;
}
return Stairs(n-1)+Stairs(n-2);
}
问题2 楼梯上有15阶台阶,上楼时可以一步上1阶,也可以一步上两阶,我们规定有7步上了一阶楼梯。编写算法计算共有多少种不同的上楼梯的方法。
这个听起来有点复杂其实我们可以想一下如果15步里7步是1阶那么还有4步是两阶,我们可以将不管这次上一阶还是两阶都称为一个step,那我们就一共有4+7=11个step那么在11个step中选择4个走两阶即可,所以其方法为
public static int Anum(int d,int p)
{
int res=1;
for(int i=0;i<p;i++)
{
res*=d;
d-=1;
}
return res;
}
public static int Cnum(int d,int p)
{
return Anum(d,p)/Anum(p,p);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(Cnum(11,4));
}
问题三:问题2 楼梯上有15阶台阶,上楼时可以一步上1阶,也可以一步上两阶,我们规定走的步数step只能为偶数。编写算法计算共有多少种不同的上楼梯的方法。
我们在递归时候将其当前所走的步数也加入参数中,每次移动都对其步数信息进行修改,如果步数为偶数,那么将其方法数加一。
public static int sum=0;
//n为剩余的楼梯数
//step为当前走的步数
public static void evenStepAboutStairs(int n,int step)
{
if(n<0)
{
return ;
}
//所有楼梯已走完且步数为偶数时,sum++
if(n==0&&step%2==0)
{
sum++;
}
//走一步,步数加一
evenStepAboutStairs(n-1, step+1);
//走两步,步数加一
evenStepAboutStairs(n-2, step+1);
}