既然是寫在前面的話,不妨訂立幾條標準。
首先以遞迴的形式定義fibonacci數列的第
n 項f(
n)的計算公式:f(
n)=簡單的if-else
語句又可進一步簡化為三目運算子:
__int64 fib(unsigned n)
雖然定義、形式和實現上都十分簡單和便於理解,二分遞迴版卻存在大量重複計算
的問題。以f(
10)的遞迴計算為例考察二分遞迴版的重複計算問題,如圖示:
解決的思路便是考慮如何利用已計算的中間值來計算當前要計算的值,劍指offer給出的解決方案是,完全不在沿用傳統的遞迴
計算(從後向前的)方式,而是採用順序的迴圈
的向後計算方式,為了方便計算需引入兩個中間變數
__int64 fibnminus1, fibnminus2;
分別表示f(
n−1)
、f(n−2)
來記錄每一次參與迴圈計算的第乙個加數和第二個加數。**如下:
__int64 fib(unsigned n)
return fbn;
}
劍指offer提供的替代方案仍然具有一定的技巧性,所謂技巧性也即不可複製性,這裡提供一種通用的解決方案,所謂的通用,是因為它利用了一種演算法思想:動態規劃(dp:dynamic programming),這裡拋開動態規劃嚴格且抽象的定義,我們從它的實現方式入手,也即記錄結果再利用
,我們來看動態規劃版本的計算方法:
long
long memo[n+1]; // 全域性變數,初始化為0
long
long fib(unsigned n)
這裡看似好像仍然是之前的遞迴形式相同,然而,通過檢視其遞迴呼叫的流程可以發現,分支的右側,已在左側計算出且儲存在mem[n]中,
。
這篇部落格的最終目的是為了引出動態規劃的演算法思想,自然想要把握動態規劃的精髓,是完全不夠的,會在以後的文章中反覆思考和探索動態規劃。
劍指Offer一刷 斐波那契數列(C )
大家都知道斐波那契數列,現在要求輸入乙個整數n,請你輸出斐波那契數列的第n項 從0開始,第0項為0,第1項是1 n 39 斐波那契數列由 0 和 1 開始,之後的斐波那契數就是由之前的兩數相加而得出。f 0 0,f 1 1 f n f n 1 f n 2 其中 n 1.解法一 最直接想到的就是遞迴。...
從斐波那契數列開始,0基礎入門遞迴和動態規劃
reference 為什麼你學不會遞迴?告別遞迴,談談我的一些經驗 告別動態規劃,連刷40道動規演算法題,我總結了動規的套路 動態規劃 理解 個人認為,遞迴和動態規劃,尤其能體現計算機程式設計的魅力。使用斐波那契數列引入了動態規劃的概念 斐波那契數列的是這樣乙個數列 1 1 2 3 5 8 13 2...
動態規劃一 斐波那契數列
題目 寫乙個函式,輸入n,求斐波那契 fibonacci 數列的第n項。斐波那契數列的定義如下 public long fib int n 以fib 5 為例 深色部分的fib 3 以及fib 2 會被重複計算,當n增大時,遞迴樹高度增加,會有更多的重複計算 因此這種遞迴方法的效率非常低 考慮到遞迴...