動態規劃系列專題講義之斐波那契數列

2021-08-20 18:22:24 字數 4351 閱讀 6231

動態規劃系列專題講義

專題一:斐波那契數列

name: 動態規劃專題之斐波那契數列 

author: 

date: 22-03-17 08:56

description: 1755_菲波那契數列

描述:斐波那契數列是指這樣的數列: 數列的第乙個和第二個數都為1,接下來每個數都等於前面2個數之和。給出乙個正整數a,要求斐波那契數列中第a個數是多少。

輸入:第1行是測試資料的組數n,後面跟著n行輸入。每組測試資料佔1行,包括乙個正整數a(1<= a <= 20)

輸出:輸出有n行,每行輸出對應乙個輸入。輸出應是乙個正整數,為菲波那契數列中第a個數的大小

樣例輸入

樣例輸出

1 #include

#include

using namespace std; 

const int maxn = 50; 

int f1[maxn];//fibonacci數列

int f2[maxn] = ;//fibonacci數列 

int fibonacci(int n); //遞迴演算法

int fibonacci_1(int n); //備忘錄:自頂而下 

int fibonacci_2(int n);//動態規劃:自底而上 

int fibonacci_3(int n);//動態規劃:降維優化

int main()  

int n, a; 

fibonacci_2(maxn);//動態規劃,先記錄所有子問題的解

cin>> n;

for(int i=0; icin>> a;

cout << fibonacci(a) << endl;

cout << fibonacci_1(a) << endl;

cout << f2[a] << endl;

cout << fibonacci_3(a) 演算法1:遞迴演算法,沒有記錄任何中間結果。

int fibonacci(int n)

if (n == 0 || n == 1)  //遞迴出口

return    //語句1

return fibonacci( ) + fibonacci( ); //語句2

問題1:將語句1和語句2補充完整。

問題1:語句1:return n;

語句2:return fibonacci(n-1) +fibonacci(n-2);

演算法2:備忘錄演算法:自頂而下,需要用到全域性變數f1 [maxn]。

int fibonacci_1(int n)  

if (f1[n] > 0)  //如果這個問題曾經計算過,直接返回  

return   //語句1

if(n == 0 || n == 1)  //遞迴出口

f1[n] =   //語句2

else

f1[n]=    //語句3

return f1[n];

問題1:將語句1,語句2和語句3補充完整。

問題2:與演算法1(遞迴演算法)相比,演算法2(備忘錄演算法)有哪些優越之處?

問題1:語句1:return f1[n];

語句2:f1[n] = n;

語句3:f1[n] = fibonacci_1(n-1) + fibonacci_1(n-2);

問題2:遞迴演算法進行了重複計算,而備忘錄演算法利用一維陣列f1[n]記錄了子問題的解,無需重複計算,大大提高了效率。

演算法3:動態規劃:自底而上,需要用到全域性變數int f2[maxn] =;。

int fibonacci_2(int n)

for (int i=2; i<=n; i++) 

f2[i] =   //語句1

return f2[n]; 

問題1:將語句1補充完整。

問題2:與演算法2(備忘錄演算法)相比,演算法3(動態規劃)有哪些異同?

問題1:語句1:f2[i] = f2[i-1] + f2[i-2];

問題2:備忘錄和動態規劃演算法都是利用遞推表示式獲得子問題的解,並記錄了子問題的解,用空間換時間,提高了時間效率。但是二者的思考方向不同,備忘錄演算法是自頂而下,從最終解出發,採用遞迴的方式來求解;動態規劃演算法是自底而上,從最小的子問題出發,逐步向上求出較大問題的解,直到獲得最終解。

演算法4:/動態規劃:降維優化,使用3個變數代替一維陣列。

int fibonacci_3(int n)

intcur, pre1, pre2;

pre1= 0, cur = pre2 = 1; //初始化

for (int i=2; i<=n; i++) //自底向上,迭代更新變數值

cur=     //語句1

pre1 =    //語句2

pre2 =    //語句3

return cur; 

問題1:將語句1,語句2和語句3補充完整。

問題2:與演算法3(基本動態規劃演算法)相比,演算法4(動態規劃降維優化)有哪些異同?

問題1:語句1:cur = pre1 + pre2; 

語句2:pre1 = pre2;

語句3:pre2 = cur;

問題2:二者同屬動態規劃演算法,都利用額外的變數(或陣列)記錄了各個子問題的解,都是從最小的子問題出發,逐步向上求出較大問題的解,直到獲得最終解。演算法3保留了所有子問題的解,雖然需要較多的空間,但是一次計算之後,就可以直接輸出任意解了;演算法4利用斐波那契數列遞推公式的特性,只保留了每個元素的當前值和它前面的2個元素值,對計算過程中產生的子問題解用過即棄,所需空間較少,但每次求解新元素的值,都需要從頭開始計算,適用於只需要求某乙個元素值的情形。

課後練習:

練習1:1788_pell數列

描述:pell數列a1, a2, a3, ...的定義是這樣的,a1 = 1, a2 = 2, ... , an = 2* an-1 + an - 2 (n > 2)。

給出乙個正整數k,要求pell數列的第k項模上32767是多少。

輸入:第1行是測試資料的組數n,後面跟著n行輸入。每組測試資料佔1行,包括乙個正整數k (1 ≤ k < 1000000)。

輸出:n行,每行輸出對應乙個輸入。輸出應是乙個非負整數。

樣例輸入

樣例輸出

練習2:3089_爬樓梯

描述:樹老師爬樓梯,他可以每次走1級或者2級,輸入樓梯的級數,求不同的走法數。

例如:樓梯一共有3級,他可以每次都走一級,或者第一次走一級,第二次走兩級也可以第一次走兩級,第二次走一級,一共3種方法。

輸入:輸入包含若干行,每行包含乙個正整數n,代表樓梯級數,1<= n <= 30

輸出:不同的走法數,每一行輸入對應一行輸出

樣例輸入

樣例輸出

練習3:2046_骨牌鋪方格

描述:在2×n的乙個長方形方格中,用乙個1× 2的骨牌鋪滿方格,輸入n ,輸出鋪放方案的總數。例如n=3時,為2× 3方格,骨牌的鋪放方案有三種,如下圖:

輸入:輸入資料由多行組成,每行包含乙個整數n,表示該測試例項的長方形方格的規格是2×n(0輸出:對於每個測試例項,請輸出鋪放方案的總數,每個例項的輸出佔一行。

樣例輸入13

2樣例輸出13

2練習4:2718_移動路線

描述:桌子上有乙個m行n列的方格矩陣,將每個方格用座標表示,行座標從下到上依次遞增,列座標從左至右依次遞增,左下角方格的座標為(1,1),則右上角方格的座標為(m,n)。

小明是個調皮的孩子,一天他捉來乙隻螞蟻,不小心把螞蟻的右腳弄傷了,於是螞蟻只能向上或向右移動。小明把這只螞蟻放在左下角的方格中,螞蟻從左下角的方格中移動到右上角的方格中,每步移動乙個方格。螞蟻始終在方格矩陣內移動,請計算出不同的移動路線的數目。

對於1行1列的方格矩陣,螞蟻原地移動,移動路線數為1;對於1行2列(或2行1列)的方格矩陣,螞蟻只需一次向右(或向上)移動,移動路線數也為1……對於乙個2行3列的方格矩陣,如下圖所示:

|(2,1)|(2,2)|(2,3)|

|(1,1)|(1,2)|(1,3)|

螞蟻共有3種移動路線:

路線1:(1,1) → (1,2) → (1,3) → (2,3)

路線2:(1,1) → (1,2) → (2,2) → (2,3)

路線3:(1,1) → (2,1) → (2,2) → (2,3)

輸入輸入只有一行,包括兩個整數m和n(0輸出

輸出只有一行,為不同的移動路線的數目。

樣例輸入

2 3樣例輸出

pan � f)=np��ج → (1,2) → (2,2) → (2,3)

路線3:(1,1) → (2,1) → (2,2) → (2,3)

輸入輸入只有一行,包括兩個整數m和n(0輸出

輸出只有一行,為不同的移動路線的數目。

樣例輸入

2 3樣例輸出

動態規劃之斐波那契數

70.爬樓梯 e 假設你正在爬樓梯。需要 n 階你才能到達樓頂。每次你可以爬 1 或 2 個台階。你有多少種不同的方法可以爬到樓頂呢?注意 給定 n 是乙個正整數。第n階台階的路線等於n 1階的路線數加上n 2階的路線數,第一階的路線數為1,第二階路線數等於2,遍歷求和即可 class soluti...

動態規劃 斐波那契數列

問 大家都知道斐波那契數列,現在要求輸入乙個整數n,請你輸出斐波那契數列的第n項 從0開始,第0項為0 n 39 斐波那契數列簡單介紹 我的解法 注 從fibonacci n 1 fibonacci n 2 明顯看出使用的是遞迴,此題用遞迴兩三行 即可搞定。但是,若出題者準備著乙個超大的n,那麼很有...

斐波那契系列

91.解碼方法 一條包含字母a z的訊息通過以下方式進行了編碼 a 1 b 2 z 26給定乙個只包含數字的非空字串,請計算解碼方法的總數。示例 1 輸入 12 輸出 2 解釋 它可以解碼為 ab 1 2 或者 l 12 示例 2 輸入 226 輸出 3 解釋 它可以解碼為 bz 2 26 vf 2...