c语言母牛的故事分析函数解决,[递归]母牛的故事-三种题解(C语言代码)

###### **分析问题**

看到这道题,如果没有明显的思路

可以试着列出一些简单的数据

| 年份 |1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |

| ------------ | ------------ | ------------ | ------------ | ------------ | ------------ | ------------ | ------------ | ------------ |

| 总数 | 1 | 2 | 3 | 4 | 6 | 9 | 13 | 19 |

| 成牛 | 1 | 1 | 1 |1 | 2 | 3 | 4 | 6 |

`成牛就是可以生育的牛`

那么我们就能发现显然的规律了.

假设第N年的牛的总数为F(n)

那么前四年中 **F(n) = n**

后面的年份里 **F(n) = F(n-1) + F(n-3)**

也很好理解,某年的牛的总数量=去年的总数+成牛所生的数量

而成牛的数量会正好与前面第三年牛总数相等,这是小牛长大的时间

那么知道了边界和递推关系,我们就可以用递归解决问题.

###### 第一种解法-递归

```c

#include//递归函数

int dfs(int year){

if(year<5)//边界

return year;

//递推式

return dfs(year-1)+dfs(year-3);

}

int main()

{

int input[20]={0};//存储输入的数

int i=0,j=0;

int n;

//输入部分

//输入部分本来应该动态分配内存,但我懒

//而且这个也确实占不到多少内存

while(1){

scanf("%d",&n);

if(n == 0) break;

input[i]=n;

i++;

}

//输出部分

while(i--){

printf("%d\n",dfs( input[j++] ));

}

return 0;

}

```

递归虽然简单,但是,时间复杂度极高

我试了一下 第55年 在我的电脑上算了大概有1s

这样的答案可能会超时,所以要改进.

###### 第二种解法-带有记忆化搜索的递归

#include//记忆化搜索

int answer[56]={0}; //存储每年的答案

//因为不可能某一年为0,所以以0判断空

int dfs(int year){

if(year<5)

return year;

//后面的年份返回的都将是数组中的年份

if( answer[year]==0 )

answer[year]=dfs(year-1)+dfs(year-3);

return answer[year];

}

int main()

{

int input[20]={0};

int i=0,j=0;

int n;

//输入部分

while(1){

scanf("%d",&n);

if(n == 0) break;

input[i]=n;

i++;

}

//输出部分

while(i--){

printf("%d\n",dfs( input[j++] ));

}

return 0;

}

###### 第三种解法-动态规划

/*动态规划就是在现有答案可以利用

之前的结果推断的情况下,利用数组

来存取答案,将所有答案动态解出 */

#includeint main()

{

int input[20]={0};

int answer[56]={0};

int i=0,j=0;

int n;

//输入数据

while(1){

scanf("%d",&n);

if(n == 0) break;

input[i]=n;

i++;

}

//计算答案

//动态规划代码:

for(int i=1;i<5;i++)

answer[i]=i;

for(int i=5;i<56;i++)

answer[i]=answer[i-1]+answer[i-3];

//与递归的代码相似,但利用循环来解决

//answer[year]=dfs(year-1)+dfs(year-3);

//输出数据

while(i--){

printf("%d\n",answer[input[j++]]);

}

return 0;

}

都看到这里了,不点个赞

刷个666码?

0.0分

8 人评分

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值