递归问题:走楼梯、线与面

  1. 一个楼梯有n (n >= 1)级,每次走1级或两级,请问从1级台阶走到第n级台阶一共有多少种走法(假设一开始站在第0级台阶上)
    我自己理解是达到f(n)的前一步有两种情况
    走一步:f(n-1) 我刚开始理解是为什么不是加f(n)=f(n-1)+1???兄弟们关键字“走法”,你就剩一步了,你莫得选择,你只能走一步,这不是不能加到走法里面的,如果题目是“每次走1级”而不是“每次走1级或两级”,f(n)=f(n-1)=f(n-2)…=1
    走两步:f(n-2) 这是另一种方式
    到达f(n)的方法为上面两种方式相加,比较难理解了 唉 也可以抛开题意 直接看数组规律 更好理解
package com.homework.homework0716;

/**
 * @Author kinmon
 * @Date 2020/7/16 19:58
 * @Version 1.0
 * 1. 一个楼梯有n (n >= 1)级,每次走1级或两级,请问从1级台阶走到第n级台阶一共有多少种走法(假设一开始站在第0级台阶上)
 * 递归及动态规划
 * 分析得递推公式:coutWays(n) = count(n-1) + count(n-2)    countWays(1) = 1  countWays(2) = 2 //递归终止条件
 */
public class Upstairs {
    public static void main(String[] args) {
        int n = 5;
        int countWays = countWaysOne(n);
        System.out.println("    递归:" + n + "层楼梯共有" + countWays + "种方式上楼");
        int countWaysDp = countWaysDp(n);
        System.out.println("动态规划:" + n + "层楼梯共有" + countWays + "种方式上楼");
    }
    public static int countWaysOne(int n){
        //定义结束条件
        if(n == 1 || n == 2){
            return n;
        }
        return countWaysOne(n-1) + countWaysOne(n -2);
    }
    public static int countWaysDp(int n){
        int[] ways = new int[n+1];
        ways[1] = 1;
        ways[2] = 2;
        for (int i = 3; i < n+1; i++) {
            ways[i] = ways[i-1] + ways[i-2];
        }
        return ways[n];
    }
}

2、计算n条直线最多能把平面分成多少部分?

package com.homework.homework0716;

/**
 * @Author kinmon
 * @Date 2020/7/16 20:29
 * @Version 1.0
 * 2. 计算n条直线最多能把平面分成多少部分? n >= 1
 * 分析:得固定公式Block(n) = 1 + n * (n + 1) / 2 ? emmmm
 * 用递归做
 * 分析规律
 * 线条数:1  2  3  4   5
 *     块:2  4  7  11  16
 *可知:Blcok(n) = Block(n-1) + n    Block(1) = 1(递归终止条件)
 */
public class CutBlock {
    public static void main(String[] args) {
        int n = 5;
        int blocks = countBlocks(n);
        System.out.println(n + "条线可以把平面分为" + blocks + "块");
    }
    public static int countBlocks(int n){
        if(n == 1) {
            return 2;
        }
        return countBlocks(n - 1) + n;
    }
}

3、猴子第一天摘了若干个桃子,当即吃了一半,还不解馋,又多吃了一个; 、第二天,吃剩下的桃子的一半,还不过瘾,又多吃了一个;以后每天都吃前一天剩下的一半多一个,到第10天想再吃时,只剩下一个桃子了。问第i(i的取值范围为[1, 10])天的桃子个数?
//逆着的递归 还行

package com.homework.homework0716;

/**
 * @Author kinmon
 * @Date 2020/7/16 20:47
 * @Version 1.0
 * 3. 猴子第一天摘了若干个桃子,当即吃了一半,还不解馋,又多吃了一个; 、第二天,吃剩下的桃子的一半,还不过瘾,又多吃了一个;
 * 以后每天都吃前一天剩下的一半多一个,到第10天想再吃时,只剩下一个桃子了。问第i(i的取值范围为[1, 10])天的桃子个数?
 * 分析规律: 假设桃子总数为P,天数n
 * 天数:    1         2          3               ... 10
 * 吃前:   P(n)      P(n-1)/2-1  P(n-1)/2-1      ... 1
 * 可得:P(n) = P(n-1)/2 -1    P(10) = 1
 */
public class MonkeyPeach {
    public static void main(String[] args) {
        int n = 5;
        int peachNum = countPeach(n);
        System.out.println("第" + n + "天桃子数量为" + peachNum);
    }
    public static int countPeach(int n) {
        if(n == 10){
            return 1;
        }
        //得反着求前一天的数量
        return (countPeach(n + 1) + 1) * 2;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值