母牛繁殖问题:一头母牛,每年年初生一头小母牛,每头小母牛从第四个年头起,每年年初也要生一头小母牛,问:第20个年头后共有多少只牛?

一头母牛,每年年初生一头小母牛,每头小母牛从第四个年头起,每年年初也要生一头小母牛。

母牛繁殖问题:一头母牛,每年年初生一头小母牛,每头小母牛从第四个年头起,每年年初也要生一头小母牛,问:第20个年头后共有多少只牛?_第1张图片

从上面我们可以看出,每一代的数目就像是多个相似三角形一样,为此画出下面的图形

母牛繁殖问题:一头母牛,每年年初生一头小母牛,每头小母牛从第四个年头起,每年年初也要生一头小母牛,问:第20个年头后共有多少只牛?_第2张图片

这样的话所有子代的的数目很明显就是,绿色线条长度所代表数目的总和。

也就是:

sum = 5 + 10 + 15 + (n - 15) + (n - 10) + (n - 5) + n;

同时又要加上最初的那头母牛:sum = sum + 1;

分析出来,其实就是一个以5为初始值,以5为公差的等差数列的前n项和 Sn。

算法上可以随便用:

算法1:迭代

  • F(n) = F(n - 1) +5;
#include 
int func(int year){

    if(year == 1){

        return 5;

    }

    return func(year - 1) + 5;
}

int main(){

    int result = func(20);

    cout<return 0;
}

算法2:数学公式法

  • 根据等差数列前n项和的数学求法:
    - Sn = n(a1 + an)/2
    - 因为这里我们只知道 an 以及 公差:5,并不知道n是多少,为此我们可以变换公式。
    - Sn = (an - a1)^2/2d
#include 
int func(int year){

    int result = (year - 5)*(year - 5)/10;

    return result;
}

int main(){

    int result = func(20);

    cout<<result<
    return 0;
}

说到这里,还有一个十分严重的问题:如果n = 21的时候呢?它的最初项会是5么?

简单验证一下:21 - 5 = 16 - 5 = 11 - 5 = 6;
显然最初项是6,那么还可以有一代的,6 - 5 = 1;

那么这样的话,前面的算法分析,是有错误的!!!

如何解决这个问题呢?

     - 既然我们不知道第一项究竟是多少,我们可以利用n来求出这个我们刚开始忽略的第一项
     - 第一项其实就是:n % 5 + 5
     - 项数其实就是: n / 5 -1

根据上面的分析再次修改上面的算法代码:

迭代法修改

#include 
int func(int year,int start){

    if(year == 1){

        return start;

    }

    return func( (year - 1) ,start) + 5;
}

int main(){

    int result = func(20 , 20 % 5 + 5);

    cout<return 0;
}

公式法修改

#include 
int func(int year,int start){

    int result = (year - start)*(year - start)/10;

    return result;
}

int main(){

    int result = func(20, 20 % 5 + 5);

    cout<return 0;
}

你可能感兴趣的:(C语言问题)