演算法設計與分析 遞推演算法

2021-10-05 19:23:09 字數 3750 閱讀 1368

遞推法的概念:

遞推法是一種重要的數學方法,在數學的各個領域中都有廣泛的運用,也是計算機用於數值計算的乙個重要演算法。這種演算法特點是:乙個問題的求解需一系列的計算,在已知條件和所求問題之間總存在著某種相互聯絡的關係,在計算時,如果可以找到前後過程之間的數量關係(即遞推式),那麼,從問題出發逐步推到已知條件,此種方法叫逆推。無論順推還是逆推,其關鍵是要找到遞推式。這種處理問題的方法能使複雜運算化為若干步重複的簡單運算,充分發揮出計算機擅長於重複處理的特點。

遞推演算法的首要問題是得到相鄰的資料項間的關係(即遞推關係)。遞推演算法避開了求通項公式的麻煩,把乙個複雜的問題的求解,分解成了連續的若干步簡單運算。一般說來,可以將遞推演算法看成是一種特殊的迭代演算法。

【例1】數字三角形。如下所示為乙個數字三角形。請編乙個程式計算從頂到底的某處的一條路徑,使該路徑所經過的數字總和最大。只要求輸出總和。

1、 一步可沿左斜線向下或右斜線向下走;

2、 三角形行數小於等於100;

3、 三角形中的數字為0,1,…,99;

測試資料通過鍵盤逐行輸入,如上例資料應以如下所示格式輸入:57

3 88 1 0

2 7 4 4

4 5 2 6 5

【演算法分析】

此題解法有多種,從遞推的思想出發,設想,當從頂層沿某條路徑走到第i層向第i+1層前進時,我們的選擇一定是沿其下兩條可行路徑中最大數字的方向前進,為此,我們可以採用倒推的手法,設a[i][j]存放從i,j 出發到達n層的最大值,則a[i][j]=max,a[1][1] 即為所求的數字總和的最大值。

【參考程式】

#include

using

namespace std;

intmain()

cout<

[1]<

}

【例2】滿足f1=f2=1,fn=fn-1+fn-2的數列稱為斐波那契數列(fibonacci),它的前若干項是1,1,2,3,5,8,13,21,34……求此數 列第n項(n>=3)。即:f1=1 (n=1) f2=1 (n=2) fn=fn-1 + fn-2 (n>=3)

程式如下:

#include

#include

using

namespace std;

intmain()

printf

("%d\n"

,f2)

;return0;

}

有關fibonacci數列,我們先來考慮乙個簡單的問題:樓梯有n個台階,上樓可以一步上一階,也可以一步上兩階。一共有多少種上樓的方法?    這是一道計數問題。在沒有思路時,不妨試著找規律。n=5時,一共有8種方法:5=1+1+1+1+15=2+1+1+15=1+2+1+15=1+1+2+15=1+1+1+25=2+2+15=2+1+25=1+2+2    其中有5種方法第1步走了1階(背景灰色),3種方法第1步走了2階,沒有其他可能。假設f(n)為n個台階的走法總數,把n個台階的走法分成兩類。    第1類:第1步走1階,剩下還有n-1階要走,有f(n-1)種方法。    第2類:第1步走2階,剩下還有n-2階要走,有f(n-2)種方法。    這樣,就得到了遞推式:f(n)=f(n-1)+f(n-2),不要忘記邊界情況:f(1)=1,f(2)=2。把f(n)的前幾項列出:1,2,3,5,8,……。    再例如,把雌雄各一的一對新兔子放入養殖場中。每只雌兔在出生兩個月以後,每月產雌雄各一的一對新兔子。試問第n個月後養殖場中共有多少對兔子。 

【例3】 有 2χn的乙個長方形方格,用乙個1*2的骨牌鋪滿方格。

編寫乙個程式,試對給出的任意乙個n(n>0), 輸出鋪法總數。

【演算法分析】

(1)面對上述問題,如果思考方法不恰當,要想獲得問題的解答是相當困難的。可以用遞推方法歸納出問題解的一般規律。

(2)當n=1時,只能是一種鋪法,鋪法總數有示為x1=1。

(3)當n=2時:骨牌可以兩個並列豎排,也可以並列橫排,再無其他方法,如下左圖所示,因此,鋪法總數表示為x2=2;

(4)當n=3時:骨牌可以全部豎排,也可以認為在方格中已經有乙個豎排骨牌,則需要在方格中排列兩個橫排骨牌(無重複方法),若已經在方格中排列兩個橫排骨牌,則必須在方格中排列乙個豎排骨牌。如上右圖,再無其他排列方法,因此鋪法總數表示為x3=3。

由此可以看出,當n=3時的排列骨牌的方法數是n=1和n=2排列方法數的和。

(5)推出一般規律:對一般的n,要求xn可以這樣來考慮,若第乙個骨牌是豎排列放置,剩下有n-1個骨牌需要排列,這時排列方法數為xn-1;若第乙個骨牌是橫排列,整個方格至少有2個骨牌是橫排列(1*2骨牌),因此剩下n-2個骨牌需要排列,這是骨牌排列方法數為xn-2。從第一骨牌排列方法考慮,只有這兩種可能,所以有:

xn=xn-1+xn-2 (n>2)

x1=1

x2=2

xn=xn-1+xn-2就是問題求解的遞推公式。任給n都可以從中獲得解答。例如n=5,

x3=x2+x1=3

x4=x3+x2=5

x5=x4+x3=8

下面是輸入n,輸出x1~xn的c++程式:

#include

using

namespace std;

intmain()

}

下面是執行程式輸入 n=30,輸出的結果:

input n: 30

x[1]=1

x[2]=2

x[3]=3

…x[29]=832040

x[30]=1346269

問題的結果就是有名的斐波那契數。

【例4】昆蟲繁殖

【問題描述】

科學家在熱帶森林中發現了一種特殊的昆蟲,這種昆蟲的繁殖能力很強。每對成蟲過x個月產y對卵,每對卵要過兩個月長成成蟲。假設每個成蟲不死,第乙個月只有一對成蟲,且卵長成成蟲後的第乙個月不產卵(過x個月產卵),問過z個月以後,共有成蟲多少對?0=#include

using

namespace std;

intmain()

,b[101]=

,i,j,x,y,z;

cin>>x>>y>>z;

for(i=

1;i<=x;i++

)for

(i=x+

1;i<=z+

1;i++

)//因為要統計到第z個月後,所以要for到z+1

cout<

<

return0;

}```【例5】位數問題

【問題描述】

在所有的n位數中,有多少個數中有偶數個數字3?由於結果可能很大,你只需要輸出這個答案對12345取餘的值。

【輸入格式】

讀入乙個數n

【輸出格式】

輸出有多少個數中有偶數個數字3。

【輸入樣例】

2【輸出樣例】

73【資料規模】

1<=n<=

1000

【樣例說明】

在所有的2位數字,包含0個3的數有72個,包含2個3的數有1個,共73個

【參考程式】

```cpp

#include

using

namespace std;

intmain()

cout<

];return0;

}

演算法設計與分析2 遞推演算法

遞推法是一種重要的數學方法。這種演算法特點是 乙個問題的求解需一系列的計算,在已知條件和所求問題之間總存在著某種相互聯絡的關係,在計算時,如果可以找到前後過程之間的數量關係 即遞推式 那麼,從問題出發逐步推到已知條件,此種方法叫逆推。無論順推還是逆推,其關鍵是要找到遞推式。遞推演算法的首要問題是得到...

演算法設計與分析 遞推演算法及例題

遞推演算法 演算法特點是 乙個問題的求解需一系列的計算,在已知條件和所求問題之間總存在著某種相互聯絡的關係,在計算時,如果可以找到前後過程之間的數量關係 即遞推式 那麼,從問題出發逐步推到已知條件,此種方法叫逆推。數字三角形 如上圖所示為乙個數字三角形。請編乙個程式計算從頂到底的某處的一條路徑,使該...

演算法設計與分析 第二章 遞推演算法

遞推法是一種重要的數學方法,在數學的各個領域中都有廣泛的運用,也是計算機用於數值計算的乙個重要演算法。這種演算法特點是 乙個問題的求解需一系列的計算,在已知條件和所求問題之間總存在著某種相互聯絡的關係,在計算時,如果可以找到前後過程之間的數量關係 即遞推式 那麼,從問題出發逐步推到已知條件,此種方法...