解题思路:

        将此题中按照 第6年 画出树状图: (数字为奶牛的年龄)

        dotcpp_1004.png

        由此可见: 只要求得第一个奶牛的子孙数量 + 自身 就是 第六年的答案:

        第一个奶牛的子孙的数量 = 孩子的数量 + 能生产的孩子的子孙数量。

        依此类推 此题适合使用递归方式来解题:


    递归公式 :
        我们设T(age) 为 求 年龄为 age 的奶牛的子孙的数量,则
        T(age) = 0  , 当age < 4 时, 代表不能生产
        = age - 3 , 当 4=<age <7 的时候, 因为他们的只有孩子
        = T(4) +.........+T(age-3) + age-3 , 当 7=<age有孙子  
          由递归公式可得: 第六年的奶牛的数量为 T(6+2) + 1 个

        优化:

            

                递归当中存在很多的重复的计算, 比如计算 第 6 年 和 第 7 年的时候, 都会重复的计算 T(5),T(4) ,                     而伴随这n的增大, 重复的计算的次数就越多, 因此设置一个缓存, 表示计算过指定的年龄的奶                            牛的数量, 直接从缓存当中取出, 不用在去递归了。

                                


注意事项:

        

                这种树状结构能画出的图, 有时候使用递归方式能写出简洁的代码, 若小规模问题是大规模问题的                    一 个子集, 明显可以设置一个缓存去优化递归的深度。


参考代码:

#include <iostream>
using namespace std;

int ageMap[58];  //定义一个缓存用于存储已经计算过的值了
long long func(int);

int main()
{
	int n;
	while(cin >> n && n)
	{
		long long sum = func(n+2);
		cout << (sum + 1) << endl;
	}
	return 0;
}


/* age 的值 为 n+2 , 代表第一只奶牛的年龄 */
long long func(int age) 
{
	
	if(ageMap[age])				   // 已经计算过了, 从缓存当中取得
		return ageMap[age];

	long long sum = age -3;        // 当前奶牛的孩子的数量;
	for(int i = 4; i<=age-3; ++i)  // 遍历能生产的孩子, 获取其孩子的子孙数量
		 if(!ageMap[i])
		 	sum  += func(i);     
		 else
		 	sum  += ageMap[i];     // 从缓存当中读取值 

	ageMap[age] = sum;			   // 记录缓存
	return sum;
}


点赞(0)
 

0.0分

1 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论