/**
* 猴子爬山问题:一个猴子在一座有台阶的山上爬山跳跃,猴子上山一步可跳1级或跳3级,试求猴子上山有多少种不同的跳法(假设台阶不超过50阶)
* <p>
* 注:一般台阶数不允许太高,因为有可能超过固定类型数字的表示范围
*/
public class ClimbMountains {

public static void main(String[] args) {
// 台阶阶数
int top = 30;

// 初始化数组,+4防止下标越界,使用long类型可以使台阶数稍微高一些
long[] arr = new long[top + 4];

// 爬山有多少种方法
long ways = process(0, top, arr);
System.out.println(ways);
}

/**
* 猴子爬山有多少种方法
*
* @param step 猴子当前在哪一级台阶
* @param top  台阶顶部
* @param arr  当前最高top阶的情况下,在step阶的不同跳法总数
* @return 多少种方法
*/
private static long process(int step, int top, long[] arr) {
// 登顶 算一种跳法
if (step == top) {
return 1;
}
// 超过了顶部,不算
if (step > top) {
return 0;
}
// 下一步跳1阶 的方法数
int up1 = step + 1;
if (arr[up1] == 0) {
arr[up1] = process(up1, top, arr);
}
// 下一步跳3阶 的方法数
int up3 = step + 3;
if (arr[up3] == 0) {
arr[up3] = process(up3, top, arr);
}
// 下一步的方法总数
return arr[up1] + arr[up3];
}

}