原创
问题描述:
有N阶台阶,每一步可以走1步台阶或者2步台阶,求出走到第N阶台阶的方法数。
解题思路:
- 类似于建立树的过程
1 2
1 2 1 2
1 2 1 2 1 2 1 2
…….. ........
如上,建立一棵根节点为1和一棵根节点为2的二叉树,分别表示台阶第一步跨1步和跨2步,
第二层各有两种选择,分别是跨1步和2步,接下来的每一层都有这两种选择,如何跨
越的阶数等于N,计数变量+1,如果大于N,返回继续走其他路径。
(由于n到45左右时数据已经爆炸,这种暴力递归法在n较大时系统出不来数据了)
#include<stdio.h> int count; //计数变量 void sos(int n,int step)
{
if(step>n) //大于n,这种方法不行
return;
if(step==n)
{
count++;
return;
} sos(n,step+); //树1
sos(n,step+); //树2
} int main()
{
int n;
scanf("%d",&n); //n阶台阶 sos(n,);
printf("%d",count);
return ;
}
2. 动态规划法
有一个规律: F(n)= F(n-1)+ F(n-2);
F(n)表示当有n阶台阶时有F(n)种方法;比如F(1)= 1;F(2)= 2;F(3)= F(1)+ F(2)= 3;
下面我用我的思路尽可能让大家理解这个公式:
1. 可以这样想,需要跨越n层阶梯,那么第一步我跨1层阶梯,那么剩下n-1层阶梯,跨越这n-1阶台阶的方法
就有F(n-1)方法; 同理,第一步跨2层阶梯,那么跨越剩下的n-2层阶梯就有F(n-2)种方法。
所以跨越n层阶梯的方法数 F(n)= F(n-1)+ F(n-2);
2. 如果上面大家不理解,还可以这样理解,假如我们已经知道了F(n-1)和F(n-2),求F(n);
在F(n-2)的基础上,我们可以通过一次跨2层阶梯到达第n层,也可以通过先跨1步,再跨1步的方式到达
第n层。 我们可以这样理解,如果一次性跨2层阶梯,我们只是在每一种跨越n-2层阶梯方式的基础上再加上
2就能到达第n层阶梯了,所以方法还是F(n-2);
如果先跨1步,这样加上原来的n-2步,就一共走了n-1步了,方法数就是F(n-1)了,然后再跨多1步,同
上,我们只是在每一种跨越n-1层阶梯方式的基础上再加上1就能到达第n层阶梯了,所以方法还是F(n-1)。
希望这样说大家能理解。
如有疑问和建议,非常欢迎大家发表评论。
#include<stdio.h>
#include<stdlib.h> int sos(long long *arr,int n)
{
if(n<)
return ;
if(n== || n== || n==)
return n; if(arr[n-]==) //等于0表示没有被算出
arr[n-]=sos(arr,n-); //没有被算出,就先算出 if(arr[n-]==) //同理
arr[n-]=sos(arr,n-); return arr[n-]+arr[n-]; //等到算出arr[n-1]和arr[n-2]后就可以算出arr[n]了
} int main()
{
int n;
scanf("%d",&n); //输入台阶数 long long *arr;
arr=(long long *)malloc(sizeof(long long)*(n+)); //分配n+1个空间 int i;
for(i=;i<=n;i++) //数组全部元素置0
arr[i]=; printf("%I64d",sos(arr,n)); free(arr);
return ;
}
2018-04-06