這個為沒有經過優化前的遞迴:
#include
long
fib(
int n)
if(n==1)
return
fib(n-1)
+fib
(n-2);
}int
main()
這個是經過優化後的**:
#include
//記憶化搜尋
__int64 memo[
10001];
//設立陣列memo 大小根據題目實際大小來變化
__int64 fib
(int n)
if(n==1)
if(memo[n]==-
1)return memo[n]
;//如果memo不為初始化的-1,則說明這個數被計算過 則不需要重新進行計算
}int
main()
__int64 res=
fib(n)
;printf
("%i64d"
,res)
;return0;
}
第乙個程式的時間複雜度是指數級增長,差不多為o(2^n),計算到40-50之間就會非常慢;
第二個程式時間複雜度已經特別低了,差不多控制在o(n),計算1000的都可以算快速出來。//此時需要注意的是計算1000時可能會溢位。所以我用了__int64(和long long一樣)來定義 輸出用的i64d%
記憶化搜尋的本質還是遞迴,只是消去了重複的運算。
遞迴——自上而下的解決問題
對於多數問題,自上而下的解決比自下而上的解決會簡單
但是這個題利用自下而上也是非常簡單
動態規劃——自下而上的解決問題
#include
__int64 fib
(int n)
; a[0]
=0; a[1]
=1;for
(int i=
2;i<=n;i++
)return a[n];}
intmain()
這個的時間複雜度也為o(n);和記憶化搜尋以後的時間複雜度差不多,但是動態規劃不會使用遞迴,遞迴會占用棧空間,容易棧溢位;而且這樣對a的訪問真正的做到了只訪問一次(對fib n次),而記憶化搜尋對memo的訪問還是有重複(對fib 2n-1次),所以這個演算法更為好。 簡單斐波那契
斐波那契數列是一種非常有意思的數列,由 0 和 1 開始,之後的斐波那契係數就由之前的兩數相加。用數學公式定義斐波那契數列則可以看成如下形式 f0 0 f1 1 fn fn 1 fn 2 我們約定fn表示斐波那契數列的第n項,你能知道斐波那契數量中的任何一項嗎?輸入包括一行,包括乙個數字n 0 n ...
簡單斐波那契
斐波那契數列是一種非常有意思的數列,由 0 0 和 1 1 開始,之後的斐波那契係數就由之前的兩數相加。用數學公式定義斐波那契數列則可以看成如下形式 f 0 0f 0 0f 1 1f 1 1f n f f f n f n 1 f n 2 我們約定 f nf n 表示斐波那契數列的第 n n 項,你能...
簡單斐波那契
斐波那契數列是一種非常有意思的數列,由 0 0 和 1 1 開始,之後的斐波那契係數就由之前的兩數相加。用數學公式定義斐波那契數列則可以看成如下形式 f 0 0f 0 0f 1 1f 1 1f n f f f n f n 1 f n 2 我們約定 f nf n 表示斐波那契數列的第 n n 項,你能...