解题思路:
将此题中按照 第6年 画出树状图: (数字为奶牛的年龄)
由此可见: 只要求得第一个奶牛的子孙数量 + 自身 就是 第六年的答案:
第一个奶牛的子孙的数量 = 孩子的数量 + 能生产的孩子的子孙数量。
依此类推 此题适合使用递归方式来解题:
递归公式 : 我们设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分
1 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复