道可道,非常道

无名者,圣人也
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

大牛生小牛的问题的讨论

Posted on 2008-03-18 11:20  一岩一道  阅读(2111)  评论(11编辑  收藏  举报

引子:在jillzhang那里看到大牛小牛问题,觉得很有趣,回去研究分析一下,发现很好玩。
问题:
     一只刚出生的小牛,4年后生一只小牛,以后每年生一只。现有一只刚出生的小牛,问20年后共有牛多少只?

研究完,发现这是一个变形的Fibonacci数列。
首先,要分清楚第一年和1年后是不同的。第一年等于0年后,所以条件是4年后即第五年生一只小牛。
注意,这个条件理解不一样可是会得出不同的结果的。
设n年后,牛共有S(n)头则可以推出:S(n)=S(n-1)+S(n-4)。
推导过程如下:
n年后的牛的年龄为n岁,设0,1,2,3岁的牛(均为无生育能力)的个数分别为a(n),b(n),c(n),d(n),大于等于4岁的牛的个数为k(n)。注意:这里0岁指小牛刚出生。
则n年后S(n)=k(n)+a(n)+b(n)+c(n)+d(n)----------------------等式1
则n+1年后
0岁的小牛个数d(n+1)=k(n+1)  //注意这里:事实上,1年后包括刚到4岁的牛都会立即生下一个小牛。
1岁小牛个数为c(n+1)=d(n)
2岁小牛个数为b(n+1)=c(n)
3岁小牛个数a(n+1)=b(n)
大于等于4岁的牛的个数为k(n+1)=k(n)+a(n)
总牛数:S(n+1)=k(n+1)+a(n+1)+b(n+1)+c(n+1)+d(n+1)
                      =(k(n)+a(n))+b(n)+c(n)+d(n)+k(n)+a(n)=S(n)+k(n)+a(n)

所以 k(n)+a(n)=S(n+1)-S(n)=k(n+1)由此

k(n)=S(n)-S(n-1)

所以

d(n)=k(n)=S(n)-S(n-1)
c(n)=k(n-1)=S(n-1)-S(n-2)
b(n)=k(n-2)=S(n-2)-S(n-3)

a(n)=k(n-3)=S(n-3)-S(n-4)

上面各式相加有: a(n)+b(n)+c(n)+d(n)=S(n)-S(n-4)

a(n)+b(n)+c(n)+d(n)=S(n)-k(n)  (有等式1可得)

故k(n)=S(n-4)=S(n)-S(n-1)

所以S(n)=S(n-1)+S(n-4)

上面格式相加有S(n)=S(n-1)+S(n-4)
S(n)=S(n-1)+S(n-4), (n>=4) 其中S(0)=S(1)=S(2)=S(3)=1

程序实现(递归算法):

 

        //y指y年后小牛个数
        public static int getCount(int y)
        {
            
if (y < 4)
            {
                
return 1;
            }
            
else
            {
                
return getCount(y - 1+ getCount(y - 4);
            }
        }

递推算法:

 //递推算法,y指y年后小牛个数
        public static int getCountEasy(int y)
        
{
            
int[] a = new int[51111,0 };
            
if (y < 4)
            
{
                
return 1;
            }

            
else
            
{
                
for (int i = 4; i < y+1; i++)
                
{
                    a[
4= a[3+ a[0];
                    a[
0= a[1];
                    a[
1= a[2];
                    a[
2= a[3];
                    a[
3= a[4];
                }

                
return a[4];
            }
           
        }

20年后的运行结果:
递归算法 Time:0ms Numbers:345
递推算法Time:0ms Numbers:345

60年后的运行结果:
递归算法 Time:4023ms Numbers:136886433
递推算法Time:0ms Numbers:136886433