基础算法-生兔子(JAVA)

算法题目描述

    有一对兔子,从出生后第三个月起每个月都生一对兔子,小兔子倡导第三个月后每个月又生一对兔子,假如兔子都不死,问第n(n为正整数)个月的兔子对数为多少?

算法分析

    第一个月1对兔子,第二月一对兔子。
    第三个月:第二个月的兔子个数再加上新生兔子个数。
    新生兔子个数:依据题目:从新生兔子第三个月起才会生兔子,所以第一个月的一对兔子要在第三个月生下一对新兔子;
    所以,第三个月总新生兔子数为1;
    那么,第三个月总兔子数为第二个月兔子数(1)加上第三个月新生兔子数(即第一个月兔子个数,为1) = 2;
    得到规律:新生兔子从第三个月起开始生兔子,且当前月所生兔子数为前第二个月兔子总数。以此类推:从第三个月起每个月兔子个数=前一个月兔子总数 + 前第二个月兔子总数(代表了将要出生的兔子个数)。

    公式:
        n<=2: 兔子总数=1
        n>2: 兔子总数=(n-1)月兔子总数+(n-2)月兔子总数

使用循环解决问题

    直接看算法:

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);//接受输入
        int n = scanner.nextInt();//获取月数
        int[] array = new int[n];//定义数组存储
        //第一个月和第二个月
        int i1 = 1;
        int i2 = 1;
        array[0] = i1;
        array[1] = i2;
        //从第三个月开始
        for (int i = 3;i <= 10; i++){
            //数组下标要减1
            array[i - 1] = array[i - 2] + array[i - 3];//当前月兔子数=上一个月兔子数 + 前第二个月兔子数
        }
        System.out.println(array[array.length - 1]);//打印输出当前总兔子数:即为最后一个月的兔子数
    }

使用反向递归解决问题

    由上面的分析我们知道了这个公式:
    公式:
        n<=2: 兔子总数=1
        n>2: 兔子总数=(n-1)月兔子总数+(n-2)月兔子总数

    那么基于这个公式我们知道当前月份的兔子总数=往前倒两个月份兔子总数之和,那么当给定一个月份数字,我们可以循环嵌套使用这个公式:
    比如:
        当月份为4时,那么可以转换为
                4月兔子总数=3月兔子总数 + 2月兔子总数
        其中三月兔子总数又可以转换为
                3月兔子总数=2月兔子总数+1月兔子总数
         总式子就变为
                4月兔子总数=(2月兔子总数 + 1月兔子总数) + 2月兔子总数。

        整体的计算结构我们可以归纳程一个树形结构,如下图:
图1  递归运算图
    我们从根节点往下不断进行迭代,每一个当前节点都等于下两个子节点的和,最后把这些加在一起就是最后的结果。
    算法:

public class Main {
    public static void main(String[] args) {
        int n = 10;
        System.out.println(func(n));
    }
    /**
	* 递归算法
	*/
    private static int func(int n){
    	//第一个月和第二个月特殊处理
        if (n == 1 || n == 2){
            System.out.println(1);
            return 1;
        }else {
        	//三个月以上开始递归计算
//            System.out.println("第"+n);
            return func(n-1)+func(n-2);
        }
    }
}

总结

    很多时候正向的计算往往带不来太大收益,这时候就可以考虑放过来,逆向运算。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嘻嘻哈哈笑呵呵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值