猴子爬山
问题描述
一只顽猴在一座有50级台阶的小山上爬山跳跃.上山时需要从山脚至山顶往上跳50级台阶,一步可跳2级,或跳3级,或跳4级,求上山有多少种不同的跳法?
下山时从山顶至山脚往下跳50级台阶,一步可跳1级,或跳2级,或跳3级,求下山有多少种不同跳法?
算法思路
- 问的是有多少种跳法,而不是怎么跳
- 当然也知道怎么跳也是可以记录下来的,楼梯台阶就是求怎么跳
- 这个题目一般给的都是递归的解法,非递归解法话不可取
- 非递归使用3进制的解法,数据量太大了!!!
- 如果已经知道递推公式的话,一定要写递推式子!
- 这个题目如果是递归的话,数量级是 3^50!
代码示例
Python
# 分析过程很重要
# 规定只能2,3,4这样爬
def up_hill1(layer):
"""
猴子爬山递归函数
:param layer: 层数
:return: 上楼梯需要的步数
"""
if layer in [0, 2, 3]:
return 1
if layer == 1 or layer < 0:
return 0
if layer == 4:
return 2
return up_hill1(layer - 2) + up_hill1(layer - 3) + up_hill1(layer - 4)
# 递归太慢了,如果是知道公式的话,该递归为递推
def up_hill2(layer):
way = [0] * (layer + 1)
# 初始化
way[1] = 0
way[2] = way[3] = 1
way[4] = 2
for idx in range(5, len(way)):
way[idx] = way[idx - 2] + way[idx - 3] + way[idx - 4]
return way[layer]
# 下山也是同理
def down_hill1(layer):
# 如果说是小于0的话,也就是不符合规则的爬法
if layer < 0:
return 0
if layer in [0, 1]:
return 1
if layer == 2:
return 2
if layer == 3:
return 4
return down_hill1(layer - 1) + down_hill1(layer - 2) + down_hill1(layer - 3)
def down_hill2(layer):
way = [0] * (layer + 1)
# 初始化
way[1] = 1
way[2] = 2
way[3] = 4
for idx in range(4, len(way)):
way[idx] = way[idx - 1] + way[idx - 2] + way[idx - 3]
return way[layer]
# 递归 => 递推!
# print(up_hill1(50))
print(up_hill2(50))
# print(down_hill1(50))
print(down_hill2(50))
Java
public class 猴子爬山 {
// 注意: Java的数据类型会超出范围
static long down_hill(int layer) {
long[] way = new long[layer + 1];
// 初始化
way[1] = 1;
way[2] = 2;
way[3] = 4;
for (int i = 4; i < way.length; i++) {
way[i] = way[i - 1] + way[i - 2] + way[i - 3];
}
return way[layer];
}
static int up_hill(int layer) {
int[] way = new int[layer + 1];
// 初始化
way[1] = 0;
way[2] = way[3] = 1;
way[4] = 2;
for (int i = 5; i < way.length; i++) {
way[i] = way[i - 2] + way[i - 3] + way[i - 4];
}
return way[layer];
}
public static void main(String[] args) {
System.out.println(up_hill(50));
System.out.println(down_hill(50));
}
}