C#之猴子吃桃儿问题的解法——猴子吐桃儿

简介: 猴子第一天摘了许多个桃子,先吃了所有桃子的一半,后又吃了一个;第二天又吃了剩下桃子的一半,后又吃了一个……第十天,剩1个桃子。问:猴子第一天摘了多少个桃子? 首先对“猴子吃桃”的过程进行正向推导,设:猴子第一天摘了N个桃子,第n天剩Ln个桃子。

猴子第一天摘了许多个桃子,先吃了所有桃子的一半,后又吃了一个;第二天又吃了剩下桃子的一半,后又吃了一个……第十天,剩1个桃子。问:猴子第一天摘了多少个桃子?

首先对“猴子吃桃”的过程进行正向推导,设:猴子第一天摘了N个桃子,第n天剩Ln个桃子。则——

L1 = N/2 - 1

L2 = L1/2 - 1/2 - 1

L3 = L2/2 - 1/2^2 - 1

......

Ln = L(n-1)/2 - 1;

然后对“猴子吐桃”的过程进行逆向推导,因为Ln = L(n-1)/2 - 1,所以L(n-1) = 2Ln + 2。即——

从某一天剩余的桃子量我们可以逆推出上一天的桃子量。可以想象猴子把当天吃的桃子吐了出来(先吐出一个,再吐出目前桃子数2倍的桃子),就是上一天吃剩下的桃子量。

由于我们已经知道了第10天猴子吃完桃后剩余桃子数为1,这样就可以把“第10天”和“1个桃”作为两个参数传入一个“猴子吐桃”的函数中,让猴子把吃的桃儿都吐出来,一直吐到第1天,并返回第一天猴子摘的桃子数:

using System;

namespace MonkeyEatPeaches
{
    class Program
    {
        static void Main(string[] args)
        {
            int left = 1;
            int days = 10;
            Console.WriteLine(MonkeyVomitPeaches(days, left));
            Console.ReadKey();
        }

        private static int MonkeyVomitPeaches(int days, int left)
        {
            if (days > 1)
            {
                left = (left + 1) * 2;
                days--;
                return MonkeyVomitPeaches(days, left);
            }
            else
            {
                return (left + 1) * 2;
            }
        }
    }
}

结果得出:

答:第一天猴子摘了3070个桃子。

其实这个递归法就相当于一个for循环,所以时间复杂度为O(n)。

可以进一步研究一下递归算法的时间复杂度

相关文章
|
11天前
47: 猴子吃桃
47: 猴子吃桃
|
2月前
猴子分桃
猴子分桃。
20 1
|
3月前
|
Java
小明买了一堆桃子,不知道个数,第一天吃了一半的桃子,还不过瘾,又多吃了一个。以后他每天吃剩下的桃子的一半还多一个,到n天只剩下一个桃子了。问:最开始买了多少桃子。(使用Java实现)
小明买了一堆桃子,不知道个数,第一天吃了一半的桃子,还不过瘾,又多吃了一个。以后他每天吃剩下的桃子的一半还多一个,到n天只剩下一个桃子了。问:最开始买了多少桃子。(使用Java实现)
|
9月前
1418:猴子选大王
1418:猴子选大王
|
5月前
猴子吃桃问题
猴子吃桃问题。
23 2
|
10月前
【每日一道智力题】之猴子搬香蕉
【每日一道智力题】之猴子搬香蕉
192 0
|
11月前
猴子选大王
猴子选大王
81 0
|
11月前
刷题之小蓝吃糖果和你究竟有几个好姐妹
刷题之小蓝吃糖果和你究竟有几个好姐妹
121 0
猴子吃桃子问题(循环、递归)
猴子吃桃子问题(循环、递归)
144 0