解题思路:

打表理清思路先,把牛家分大牛、三岁牛宝、两岁牛宝、一岁牛宝(虚岁,出生就是一岁啦)

2.png

在第5年时,牛宝开始陆续长成大牛,三岁牛宝就变成了大牛

同理,两岁牛宝变三岁牛宝,一岁牛宝变两岁牛宝

而新的一岁牛宝则是去年的大牛跟三岁牛宝的总牛数(三岁牛宝今年长成大牛也开始生小牛宝了)

思路理清后,就要求递推公式了,把4种牛分别用字母标记:

大牛a[]、三岁牛宝b[]、两岁牛宝c[]、一岁牛宝d[]以及牛头数s[]

可以得出第n年的各个公式:

a[n] = a[n-1]+b[n-1]

b[n] = c[n-1]

c[n] = d[n-1]

d[n] = a[n-1]+b[n-1] = a[n]

则总牛数 s[n]=a[n]+b[n]+c[n]+d[n]

    = a[n-1]+b[n-1]+c[n-1]+d[n-1]+a[n-1]+b[n-1]

    = s[n-1]+a[n-2]+b[n-2]+c[n-2]

    = s[n-1]+a[n-3]+b[n-3]+c[n-3]+d[n-3]

    = s[n-1]+s[n-3]

根据递推公式可以写出基本的递归函数如下:

int fab(int month) {
    if(month < 4) {
        return month;
    } else {
        return fab(month-1)+fab(month-3);
    }
}

但递归在月份大的时候空间复杂度跟时间复杂度都特别高,故需再用动态规划思路,在递归的过程中不断记录计算过的月份的牛头数,需要的时候可以直接调用
参考代码:

应题目要求使用递归:

#include<iostream>
using namespace std;
 
long long cow[56] = {0,1,2,3,4}; // 在main函数外定义的数组会全部自动初始化为0
 
long long fab(int month) {
    if(cow[month] == 0) { // 没有算过的月份,数组内存的是0
        cow[month] = fab(month-1) + fab(month-3);
        return cow[month];
    } else {
        return cow[month];
    }
}
 
int main () {
    int n;
    while(scanf("%d", &n) && n) cout << fab(n) << endl;
    return 0;
}

或者直接用递推公式:

#include<iostream>
using namespace std;
 
int main () {
    int cow[56] = {0,1,2,3,4};
    for(int i = 4; i < 55; i ++) cow[i] = cow[i-1] + cow[i-3];
    int n;
    while(scanf("%d", &n) && n) cout << cow[n] << endl;
    return 0;
}


点赞(0)
 

0.0分

156 人评分

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

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

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

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

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

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

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

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

评论列表 共有 49 条评论

wolf 1年前 回复TA
@Eddie 两处错误。。。。
Eddie 1年前 回复TA
@Eddie 从n<3开始貌似会增加计算机耗时,所有时间会超
Eddie 1年前 回复TA
#include<stdio.h>

int num(int n){
	if(n < 5) return n;
	else return num(n-1)+num(n-3);
}

int main(){
	int n;
	while(scanf("%d",&n) && n)
		printf("%d\n",num(n));
	}
	returrn 0;
}

注意要从n<5开始,这样时间才不会超
yunyu 1年前 回复TA
提交了不对啊!
空明 2年前 回复TA
果然还是得先找出递归公式啊
TSoul 2年前 回复TA
@LBD西瓜泥 6
PipiceDan 2年前 回复TA
真的很牛,并且帮助我理解了动态规划的思想
仙仙 2年前 回复TA
很厉害
一路上有你 2年前 回复TA
@LBD西瓜泥 6
盘旋 2年前 回复TA
@卿之朱砂 while(scanf("%d",&n)!=EOF&&n!=0)