问题

   一只刚出生的奶牛,4年生1只奶牛,以后每一年生1只。现在给你一只刚出生的奶牛,求20年后有多少奶牛。

作者实现的时候应用了规律,而我这里实现的时候,绕开规律。从一个点子入手

假设第一年一头奶牛,在N年后有多少个直系的奶牛

这还不容易,4年后,每年生一头奶牛,N-3

那么4年后的第一头奶牛,N年后有多少了直系的奶牛

这还不容易,4年后,每年生一头奶牛,N-6

 int CaculCowNum(int nYear){
    //
数组保存从第一年开始到150年,每年增加的奶牛
    int nLocalYearCow[150]={0};

    //初始化奶牛为1头
    nLocalYearCow[1]=1;

    int tmp=0;

    int nSumCow=0;

    //遍历一次,每头奶牛在以后的某年生产多少头牛
    for(int i=1;i<nYear+1;i++)
    {
        tmp=nLocalYearCow[i];

        for(int j=i+3;j<nYear+1;j++)
        {
            nLocalYearCow[j]+=tmp;
        }
    }
    
    //将每年生产的奶牛相加
    for(int i=1;i<nYear+1;i++)
    {
        nSumCow+=nLocalYearCow[i];
    }

    return nSumCow;
}

在这里没有比较效率,也没有比较算法的复杂度,仅仅是提供思考问题的一个方法。

推导

这里先给出推导的表达式: f(n+3)=f(n+2)+f(n)

详细的推导过程如下:

    现在假设1n-2年间总共有m1头奶牛,第n-1年有m2头奶牛出生,第n年有m3头奶牛出生

可以得到n年间一共有多少头奶牛:

   f(n)=m1+m2+m3

    现在到n+1年,该如何推导出现在有多少头奶牛?

    你想思考:n-1年出生的m2头奶牛此时刚出生2年不可能生奶牛,n年出生的m3头奶牛更不可能(只有一年的年龄),所以只有(n-2)年之前出生的m1头奶牛此时在n+1年会生出m1头奶牛,每一头奶牛生一头

 可以得到n+1年间一共有多少头奶牛:

    f(n+1)=m1+,m2+m3+m1

   现在到n+2年,思考如下:n-2年间的m1头奶牛会在n+2年生出m1头奶牛,n-1年间出生的奶牛因为到n+2年的时候已经有四年了,这时候也开始生产奶牛m2,n年间出生的奶牛因为只有3年的年龄所以没有牛犊。

    可以得到n+2年间一共有多少头奶牛:

   f(n+2)=m1+m2+m3+m1+(m1+m2)

这个时候整理一下看是否会有任何的推导公式:

f(n)=m1+m2+m3 1

f(n+1)=2m1+m2+m3 2

f(n+2)=3m1+2m2+m3 3

糟了,没有任何的逻辑可以推导

别急,尝试推算出n+3年的思路:

    现在到n+3年,此时会在上面的n+2年的基础上生娃,到底有那几年的奶牛可以生娃:n-2年的奶牛现在已经至少有6年的年龄,可以生出m1头奶牛,n-1年出生的奶牛有5年的年龄,可以出生m2头奶牛,n年出生的奶牛刚好有4年的年龄可以生出m3头奶牛,

   f(n+3)=m1+m2+m3+m1+(m1+m2)+(m1+m2+m3);

整理如下:

   f(n+3)=4m1+3m2+2m3 4

通过式431有没有发现

f(n+3)=f(n)+f(n+2)