不死神兔问题
今天遇到不死神兔(斐波那契数列)的问题了。
题目:有一对兔子,从出生后第3个月起每个月生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子不死,问第二十个月的兔子对数是多少?
分析题目开始:
如果按照数列来计算:
第一个月:1只
第二个月:1只
第三个月:2只
....
可以分析出一个数列为:
1 1 2 3 5 8 13 21 34 55 89 144 ...
可以看出,从第三个月开始,后面每个月都是前两个月的数量之和,来写个java代码实现一下。
代码实现:
/*** 不死神兔问题* @param n 第n月* @return*/
public static int bsst(int n){
if(n == 1 || n == 2){
//第一个月和第二个都是1 return 1;
}else{
//从第三个月开始都是他的前两个月数量之和,所以采用相加 return bsst(n-1)+bsst(n-2);
}
}
问题引申
我在想这个问题难道不是一系列符合数列规律的算法问题吗?所以通过这个不死神兔的问题提出解决一系列递归问题的解决办法。
第一步:理解题目
第二步:列出前多项可能性
第三步:找到规律,开始写代码
实践
1.先来实践第一个n的阶乘问题。
题目:求n的阶乘。
列出:
1! = 1
2! = 2 * 1!
3!= 3 * 2!
规律:n的阶乘等于他乘以他上一个数的阶乘。
代码:
/*** 求n的阶乘* @param n*/
public static int jiecheng(int n){
if(n == 1){
//1的阶乘就是他自己本身 return 1;
}else{
//大于1的n的阶乘等于他乘以比他小1的数字的阶乘 return n*jiecheng(n-1);
}
}
上面是一个阶乘的问题,正好符合我们从不死神兔中参悟的规律,下面再来一个。
2.猴子吃桃问题。猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第二天又将剩下的桃子吃掉一半,又多吃了一个。以后每天都吃了前一天剩下的一半零一个。到第10天,想吃时只剩下一个桃子了。试求第一天共摘多少桃子?
第一步:先来理解题目,概括一下就是,每天都吃剩下的桃子的一半加上一个桃子,然后到第10天就剩一个桃子,要求第一天有多少个桃子。
第二步:分析问题,列出可能性
第10天:1个桃子
第9天:
假设第9天有n个桃子,则被吃掉的有(n/2)+1,有因为第10天有一个桃子,所以n-(n/2)-1=1.
则解出n=4.
所以第9天有4个桃子。
第8天:
与上同样计算。n-(n/2)-1=4.
第8天有10个桃子。
第7天:22
所有可能性,从第10天倒叙开始
1 4 10 22 46 94 190 382 766 1534
第三步:规律,每一天都是后一天的数字加1,然后再乘以2。
代码:
/*** 猴子问题解决* @param n 天数* @return*/
public static int monkey(int n){
if(n == 10){
//如果n为10,则值为1 return 1;
}else{
//明天的桃子的数量monkey(n+1),那么今天的为 明天的加上+1,然后再乘以2,就是今天的 return (monkey(n+1)+1)*2;
}
}
阶段总结
可能上面两个问题还不够读者找到这个解决问题的规律,我们再来几个题目体会一下。
实践题目
问题:有 64 个格子,第一个格子放一粒麦子,第二个放2粒,第三个放4粒...每个格子都是前边的两倍。一共有多少粒?
规律:每个格子都是前一个格子的两倍。
代码:
/*** 格子问题* @param n 第n个格子* @return*/
public static int sum(int n){
if(n == 1){
return 1;
}else{
return sum(n-1)*2;
}
}
总结
所以,读者,您看懂了吗?点关注不迷路哟!