小问题,对递归重复调用的改进,一起来分享
Problem
設(shè)有一頭小母牛,從出生第四年起每年生一頭小母牛,按此規(guī)律,第N年時(shí)有幾頭母牛?
Input
本題有多組數(shù)據(jù)。每組數(shù)據(jù)只有一個(gè)整數(shù)N,獨(dú)占一行。(1≤N≤50)
Output
對(duì)每組數(shù)據(jù),輸出一個(gè)整數(shù)(獨(dú)占一行)表示第N年時(shí)母牛的數(shù)量
Sample Input
1
4
5
20
Sample Output
1
2
3
872
------------------------------------
最容易寫(xiě)出來(lái)的。
解決方法很簡(jiǎn)單:母牛數(shù)等于自己加上它生的小牛數(shù),再加上它的小牛們自己生的小牛,如此遞歸。
/*
此解答未被Accept
原因:運(yùn)算時(shí)間超時(shí)(1200ms,而時(shí)間限制在1000ms)
*/
#include<stdio.h>
int F(int n)
{
?int res = n<4?0:n-3;//該母牛所生的小牛數(shù)
?if(n>=4)
?{
??for(int i=1; i<=n-3; i++)//該母牛的每一個(gè)孩子再生小牛。
??{
???res += F(i);
??}
?}
?return res;
}
int main()
{
?int n;
?while( scanf("%d",&n) != EOF)
?{
??printf("%d\n",F(n)+1);
?}
?return 0;
?
}
上面解答的弱點(diǎn)是,重復(fù)計(jì)算(比如F(1)被。每一個(gè)小牛掉用了,被每一個(gè)小牛的每一個(gè)孩子調(diào)用了,如此重復(fù)下去),導(dǎo)致時(shí)間開(kāi)銷(xiāo)很大。
----------------------------
改進(jìn)的:
為了避免重復(fù)運(yùn)算,我們將用一個(gè)數(shù)組保存已經(jīng)被計(jì)算過(guò)的值,由于函數(shù)F的任何計(jì)算的結(jié)果都不會(huì)是
-1,那么我們?cè)O(shè)置數(shù)組的初始值為-1,但檢查到其值不為-1時(shí),那么它已經(jīng)被計(jì)算過(guò)了,我們就沒(méi)有必要再計(jì)算了。
/*
此解答已通過(guò)TongJi編譯,并接收
?User??????? Result?? Memory Time? Language Date?
?zhouyinhui? Accepted 56 k?? 2ms?? C++????? 2006-05-06 16:32:02
*/
?
#include<stdio.h>
#include<malloc.h>
int* arr;//用于保存運(yùn)算結(jié)果,避免遞歸調(diào)用中的重復(fù)運(yùn)算
int F(int n)
{
?int res = n<4?0:n-3;
?if(n>=4)
?{
??
??for(int i=1; i<=n-3; i++)
??{
???if( *(arr+i) == -1 )//如果未運(yùn)算該F(i)
???{
????*(arr+i) = F(i);//則運(yùn)算并保存結(jié)果
???}
???res += *(arr+i);??
??}
??
?}
?return res;
}
int main()
{
?int n;
?while( scanf("%d",&n) != EOF)
?{
??int *array = (int *)malloc(n*4);
??for(int i=0; i<n; i++)
??{
???*(array+i) = -1;
??}
??arr = array;
??printf("%d\n",F(n)+1);
?}
?return 0;
?
}
?
轉(zhuǎn)載于:https://www.cnblogs.com/zhouyinhui/archive/2006/05/06/392719.html
總結(jié)
以上是生活随笔為你收集整理的小问题,对递归重复调用的改进,一起来分享的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 高数复习笔记(同济 第七版 上下册)
- 下一篇: 02. Creating a Web F