这个问题在我学习编程语言的时候总是会遇到,会以热身题的方式出现,但是这个问题总是在心中留下一团迷雾,迟迟难以自醒,之前总是以侥幸的心理通过了就行,但坎却还在心中,想着以后肯定会遇到同样的问题,不如把问题留给今天。
问题:小明喜欢爬楼梯,他有的时候一次爬一个台阶,有的时候一次爬两个台阶。如果这个楼梯有20个台阶,小明一共有多少种爬法呢?
这个问题告诉我两件事:
①爬楼梯只能一次性爬一个或两个台阶;
②台阶的总数有20阶;
解决这个问题,可能会出现一脸懵,不知如何下手!
这时候,穷举法是一个不错的思路(我是这么认为的),利用穷举法找规律,这是十分正确的,穷举法会凝聚你对问题的思考,从而归纳规律,以解决问题;
1.穷举法
注意:采取多少次爬台阶方式后,必须保证位于台阶总数=目标数才算完成目标;
(1)思考台阶总数=1,有多少种方法?
1种,这是理所应当的,采取一次性爬1阶即可完成目标;
(2)思考台阶总数=1,有多少种方法?
2种方法;①1 + 1;② 2
(3)思考台阶总数=3,有多少种方法?
3种方法;①(1) + 2; ② (0 + 2) + 1;③(1 + 1) + 1;这时候问题变得稍微复杂起来,我们这时候换个思路,台阶=3的位置可以由第几台阶过来呢?拿这个问题来说,台阶=3的位置可以由第几个台阶爬过来呢?
答:第2阶、第1阶,这是理所应当的,我们可以这样思考,3-1=2、3-2=1,所以有两种方式,即:
第1阶台阶爬2个
第2阶台阶爬1个
此时,问题还没有解决,我们想知道当台阶总数=1或=2时,都是从哪些台阶爬过来的呢?
问题:
①台阶=1
1种方法,从第0阶爬1阶过来的,或者这样思考,1-1=0,这里不能1-2=-1,这样是不符合要求的,毕竟没有-1阶台阶。
②台阶=2
额,台阶等于2有几种爬法呢?这个问题好熟悉,哦~,原来是(2)种已经解决了这个问题,有两种方法,分别是从第0阶爬2阶,第1阶爬1阶,即2-1=1、2-2=0。
此时,我们就已经解决问题了,因为台阶=3只能从第2阶或第1阶爬过来,而爬到第2阶和第1阶共2+1=3种爬法。
所以台阶=3共2+1=3种途径。
(4)思考台阶=4,有多少种方法?
同样的思考方式,台阶=4的位置可以从哪些位置爬上来,共4-1=3、4-2=2,共两种途径。即:
第3阶爬1阶
第2阶爬2阶
①台阶=3
上面我们已经算过了,共有3种方法;即:① (1) + 2; ② (1 + 1) + 1;③ (2) + 1;
那么从台阶3到台阶=4共有3种方法;即:① ((1)+ 2))+1; ②((1+1)+1)+1;③((2)+1)+1,仔细思考括号里面的内容;
②台阶=2
上面我们也算过了,共有两种方法;即:①((1+1)+2);②((2)+2);
所以台阶=4共有3+2=5 种方法
(5)思考台阶=5,有多少种方法?
台阶=5可以由哪些位置爬上来呢?即:5-1=4、5-2=3阶爬过来,共两种途径,即:
第4阶爬1阶
第3阶爬2阶
①台阶=4
上面,我们已经算过了,到达台阶=4共有5种方法,那么从台阶4到台阶5的方法为:1+2+1+1;1+1+1+1+1;2+1+1+1;1+1+2+1;2+2+1;
②台阶=3
到达台阶=3共有3种方法,那么从台阶3到台阶5的方法为:1+2+2;2+1+2;1+1+1+2;
所以台阶=5共5+3=8种途径。
归纳
这时候,在该问题背景下,你会总结出一种规律,台阶总数=n的台阶只能从台阶n-2和n-1爬到,那么我们只要知道爬到台阶=n-1和爬到台阶=n-2的方法总数就是所求问题的解,即:
Method(n) = Method(n-1) + Method(n-2),其实这是一个斐波那契数列;
这时,n-1是不是可以由n-2和n-3获取,而n-2是不是可以由n-3和n-4获取,即:
Method(n-1) = Method(n-2) + Method(n-3)
Method(n-2) = Method(n-3) + Method(n-4)
......
直到Method(台阶总数),台阶总数=1、2时就可以求解了;这是不是一种递归的思考模式呢?
2.代码
这里仅采用C++、Java求解方法:
//JAVA
public class Test {
public static void main(String[] args) {
System.out.println(getCount(6));//13
}
public static int getCount(int n){
if(n == 1 || n == 2) return n;
return getCount(n-1) + getCount(n-2);
}
}
//C++
#include <iostream>
int getCount(int n);//函数声明
int main()
{
std::cout << getCount(7) << '\n';//21
return 0;
}
int getCount(int n)
{
if (n == 1 || n == 2) return n;
return getCount(n - 1) + getCount(n - 2);
}
3.拓展
问题:小明喜欢爬楼梯,他有的时候一次爬一个台阶,有的时候一次爬两个台阶,有的时候一次爬三个楼梯。如果这个楼梯有20个台阶,小明一共有多少种爬法呢?
(1)思考台阶总数=1,有多少种方法?
毋庸置疑,1种
(2)思考台阶总数=2,有多少种方法?
易得:2种;
(3)思考台阶总数=3,有多少种方法?
4种;分别是0+3、1+1+1、1+2、2+1;首先考虑台阶=3是从那几个台阶过来的呢?3-1=2,3-2=1,3-3=0,分别从第0、1、2阶台阶爬到台阶=3,而到达台阶=1有1种,到达台阶=2共有两种方法,台阶0到3有1种。
所以,共计4种方法。
归纳
这时候,在该问题背景下,你会总结出一种规律,台阶总数=n的台阶只能从台阶n-2、n-1和n-3爬到,那么我们只要知道爬到台阶=n-1、台阶=n-2和到台阶=n-1的方法总数就是所求问题的解,即:
Method(n) = Method(n-1) + Method(n-2) + Method(n-3);
拓展代码:
//C++
#include <iostream>
int getCount(int n);//函数声明
int main()
{
std::cout << getCount(20) << '\n';//121415
return 0;
}
int getCount(int n)
{
if (n == 1) return 1;
if (n == 2) return 2;
if (n == 3) return 4;
return getCount(n - 1) + getCount(n - 2) + getCount(n - 3);
}
//Java
public class Test {
public static void main(String[] args) {
System.out.println(getCount(20));//121415
}
public static int getCount(int n){
if (n == 1) return 1;
if (n == 2) return 2;
if (n == 3) return 4;
return getCount(n-1) + getCount(n-2) + getCount(n-3);
}
}
6366

被折叠的 条评论
为什么被折叠?



