问题:
有一个农场有一头成年母牛,每三个月后一头小牛,小牛一年后长大,长大后每三个月又可以生一头小牛,如此循环,问10年后农场一共有多少牛? (假设牛都是母牛)
分析:
1.每年有12个月,母牛每三个月可生小牛,可见生小牛的频率可以抽象成每年4个,10年就是40个单位.
2.通过穷举每只母牛40个单位里可生小牛总数,其总和便是总牛数.
3.小牛可以生小需要5个单位的成长期.
实现:
再抽取出关键的数字后,算法怎么实现呢?
1.第一只母牛,10年显然可生40只小牛.
2.这第一代的40只小牛,在40个单位里又能生多少只小牛呢?可以很快推算出40只里最大的牛拥有生育能力比起母类要少5个单位,即可生35只,第二大的是34 ,依次类推,最后是1.这显然是35的阶乘.假设Num为牛的总算的记录,那么算法可以现实为:
for(int i = 35 ; i > 0 ; i++) Num += i;
这样便计算出了第二代子牛的总数,那第三代该如何计算呢?同样第二代的35只需要类似第代的40只计算子代的方法一样,第二代的34也是如此,那么N只牛对应的子代计算的方法可以总结为
for(int i = n - 5; i > 0 ; i++) Num += i;
到此可以总结出:每代子牛对应的直接子牛总数参与上叙迭代后的Num.
具体实现:
static void CreateCattle(int n, ref int num)
{
int next = n - 5;
for (int i = next; i > 0; i--)
{
num += i; //第二代
CreateCattle(i, ref num); //第三代之后
}
}
可以发现,上叙递归的结果Num没有加进去第一代和第零代的母牛.所以需要初始化Result = 41;
int result = 41;
CreateCattle(40, ref result);
全部代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Cattle
{
class Program
{
static void Main(string[] args)
{
int result = 41;
CreateCattle(40, ref result);
Console.WriteLine("The cattles's sum is : " + result);
Console.ReadLine();
}
static void CreateCattle(int n, ref int num)
{
int next = n - 5;
for (int i = next; i > 0; i--)
{
num += i;
CreateCattle(i, ref num);
}
}
}
}
续:这里假定的是10年,算法可以延生到N年.