記憶性遞歸

遞歸有時候會出現重複計算的情況(如下例題),因此爲了提高代碼效率,就需要進記憶性遞歸——即只對第一次出現的新數據進行計算並進行保存,而對於已經計算過的結果,只需將結果取出即可。(它可以提高效率,避免計算機進行重複已做過的完全相同的工作而降低效率)

例1:
我們要求找出具有下列性質數的個數(包含輸入的自然數n):
先輸入一個自然數n(n≤1000),然後對此自然數按照如下方法進行處理:
不作任何處理;
在它的左邊加上一個自然數,但該自然數不能超過原數的一半;
加上數後,繼續按此規則進行處理,直到不能再加自然數爲止.
輸入格式
1個自然數n(n≤1000)
輸出格式
1個整數,表示具有該性質數的個數。
樣例:
輸入 #1
6
輸出 #1
6

#include<stdio.h>
int f[1002]={0};
int num(int n)
{
	f[1]=1;
	int i,sum=1; 
	if(n==1){
		return f[n];
	}
	else{
		if(f[n]==0){//如果沒做這個數的計算,就進行新計算,並進行保存 
			for(i=1;i<=n/2;i++){
				sum+=num(i);
			}
			return f[n]=sum;
		}
		else{//對於求解過的n,直接取保存的結果即可
			return f[n]; 
		}
	}
 } 
 int main()
 {
 	int n;
 	scanf("%d",&n);
 	printf("%d",num(n));
 	return 0;
 }

例2:
斐波那契數列:

#include<stdio.h>
int f[100]={0}; 
int Fibonacci(int n)
{
if(n==1||n==2)
return f[n]=1;
else{
if(f[n]==0)  //沒求解過
              		return f[n]=Fibonacci(n-1)+Fibonacci(n-2);
             else   //求解過,直接取保存的結果值
                         return f[n];
     }
}
 int main()
 {
     printf("%d\n",Fibonacci(1000)); 
     return 0;
 }

再來看看遞歸的斐波那契數列寫法:(當然還有數組循環的寫法也比遞歸更有效率)

#include<stdio.h>
int Fibonacci(int n)
{
     if(n==1||n==2)
          return 1;
     else
          return Fibonacci(n-1)+Fibonacci(n-2);
} 
int main()
{
     for(int i=1;i<100;i++){
         printf("%d ",Fibonacci(i));
     }
     printf("\n");
     return 0;
 }

總結:遞歸不一定提高效率。它優點在於,將複雜問題簡單化,“大事化小,小事易做”。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章