用对象的思想递归求解《母牛的故事》问题

来源:互联网 发布:微信电影网站源码 编辑:程序博客网 时间:2024/06/09 18:13

问题描述:有一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛? 

输入例子:2 4 5

输出例子:2 4 6

此题不难,但是在遇见这个题的时候,由于一时没想清,愣是没写出来正确的递归,事后发现有两种解法:

1.迭代法:

已知母牛每年年初生一头小母牛,小母牛第四个年头开始也会年初生一头小母牛。故第一年只有一头母牛,第二年年初母牛产下第一头小母牛注意:小母牛产下的那年算作它的第一个年头,而小母牛在第四个年头会可以生产出一头小母牛,故实际为母牛产下小牛的年数+3为它第一次生育的年份。

则从第四年开始,每年的母牛数=前一年的母牛数+三年前的母牛数(三年前即为所有今年可以生育的母牛总数)。

2.递归法:

和网上的斐波那契数列思想的递归不同,我将函数cow()看作一个具备生育功能的母牛对象,cow(int num,int n)参数num为起始母牛数量,n为剩余繁殖年数。

则第一次由主函数调用cow的时候,参数num应为1,因为起始母牛数量为1,而后自身的递归调用时,参数num应为0,因为这个可以生育的母牛本身已经被计算过一次了,只需要计算它的后代数量即可。

在代码中你会发现我在第三年(i=3)的时候便调用了cow(0,n-i),为什么不是第四年呢?原因是:所有的母牛都是第二年产出一头牛,第一年只有自身,为了保持递归结构的前后一致,我们在第三年调用,也就是2年后会产出第一头牛。也可以这么理解:所有的小母牛出生时为0岁,第四个年头会产下一头小母牛,这里不要被“第四个年头”误导,实际上第四个年头小母牛3岁。我们在第三年调用cow(0,n-i)即为小母牛1岁时调用,在两年后产子。

具体代码实现如下:

#include<iostream>using namespace std;int cow(int num,int n){if (n <=0)return 0;else{for (int i = 2; i <= n; i++)//i=2因为母牛从第二年开始产牛{if (i < 3)num++;//从3开始递归调用是因为母牛从第二年开始产子,当调用了cow()的两年后才会生出第一头牛else num += cow(0,n - i) +1;//因为可生育的这头小母牛之前已经被计算过一次,所以初始母牛数量应为0,n-i为它剩下的可以繁育的时间,+1为原本母牛今年生的牛}return num;}}int main(){int n;while (cin >> n){cout << cow(1,n)<< endl;}}