演算法設計技巧與分析答案
❶ 綆楁硶璁捐℃妧宸т笌鍒嗘瀽鍥句功鐩褰
榪欐湰涔︿互娣卞叆嫻呭嚭鐨勬柟寮忔帰璁ㄤ簡綆楁硶璁捐$殑鎶宸т笌鍒嗘瀽錛屽垎涓轟笁涓涓昏侀儴鍒:
- 鍩烘湰姒傚康鍜岀畻娉曞煎紩</
- 絎1絝</: 鐞嗚В綆楁硶鍒嗘瀽鐨勫熀紜姒傚康錛屼負鍚庣畫娣卞叆瀛︿範濂犲畾鍩虹煶銆
- 絎2絝</: 鎻愪緵蹇呰佺殑鏁板﹂勫囩煡璇嗭紝甯鍔╄昏呮帉鎻$畻娉曡儗鍚庣殑鏁板﹀師鐞嗐
- 絎3絝</: 鎺㈣ㄦ暟鎹緇撴瀯錛岃繖鏄綆楁硶璁捐$殑鏍稿績錛岀悊瑙f暟鎹緇撴瀯瀵逛紭鍖栫畻娉曡嚦鍏抽噸瑕併
- 絎4絝</: 浠嬬粛鍫嗗拰涓嶇浉浜ら泦鏁版嵁緇撴瀯錛岃繖涓や釜涓婚樺湪璁稿氱畻娉曚腑鎵婕斿叧閿瑙掕壊銆
- 鍩轟簬閫掑綊鐨勬妧鏈</
- 絎5絝</: 褰掔撼娉曟槸閫掑綊鐨勫熀紜錛屽︿範榪欎竴絝犲皢鏈夊姪浜庣悊瑙i掑綊綆楁硶鐨勮捐°
- 絎6絝</: 鍒嗘不絳栫暐鏄瑙e喅澶嶆潅闂棰樼殑鏈夋晥鎵嬫碉紝娣卞叆鐮旂┒榪欎竴絝犳湁鍔╀簬浼樺寲綆楁硶銆
- 絎7絝</: 鍔ㄦ佽勫垝錛岃В鍐沖氶樁孌靛喅絳栭棶棰樼殑甯哥敤宸ュ叿錛屽湪姝ょ珷涓浣犱細瀛︿範鍒板備綍榪愮敤銆
- 鏈鍏堝壊鎶鏈</
- 絎8絝</: 璐蹇冪畻娉曪紝閫氳繃灞閮ㄦ渶浼橀夋嫨杈懼埌鍏ㄥ矓鏈浼橈紝鏄榪欑被鎶鏈鐨勫叆闂ㄤ粙緇嶃
- 絎9-11絝</: 浠庡浘鐨勯亶鍘嗗埌NP瀹屽叏闂棰橈紝娣卞叆鐞嗚В璁$畻澶嶆潅鎬х悊璁猴紝涓轟綘鎻紺虹畻娉曡捐$殑杈圭晫銆
- 絎12-13絝</: 涓嬬晫鍜屽洖婧娉曪紝鎺㈢┒綆楁硶鏁堢巼鐨勬瀬闄愬拰絳栫暐璋冩暣鐨勭瓥鐣ャ
- 絎14-16絝</: 闅忔満綆楁硶鍜岃繎浼肩畻娉曪紝闈㈠瑰嶆潅闂棰樻椂鐨勭伒媧誨簲瀵圭瓥鐣ャ
- 絎17-18絝</: 緗戠粶嫻佸拰鍖歸厤錛屽叧閿鐨勫浘璁烘傚康鍦ㄥ疄闄呴棶棰樹腑鐨勫簲鐢ㄥ疄渚嬨
- 絎19絝</: Voronoi鍥捐В錛屽嚑浣曠┖闂翠腑鐨勭畻娉曞簲鐢錛岀洿瑙傚睍紺虹畻娉曞湪瀹為檯鍦烘櫙涓鐨勮繍浣溿
❷ 演算法設計技巧與分析里第一章的題目求解答
n!/2^n+n^(n/2) =Θ(n!/2^n)
因為
所以
n!/2^n >> n^(n/2)
❸ 請教高人 遞歸演算法編寫思路技巧
一個子程序(過程或函數)的定義中又直接或間接地調用該子程序本身,稱為遞歸。遞歸是一種非常有用的程序設計方法。用遞歸演算法編寫的程序結構清晰,具有很好的可讀性。遞歸演算法的基本思想是:把規模大的、較難解決的問題變成規模較小的、易解決的同一問題。規模較小的問題又變成規模更小的問題,並且小到一定程度可以直接得出它的解,從而得到原來問題的解。
利用遞歸演算法解題,首先要對問題的以下三個方面進行分析:
一、決定問題規模的參數。需要用遞歸演算法解決的問題,其規模通常都是比較大的,在問題中決定規模大小(或問題復雜程度)的量有哪些?把它們找出來。
二、問題的邊界條件及邊界值。在什麼情況下可以直接得出問題的解?這就是問題的邊界條件及邊界值。
三、解決問題的通式。把規模大的、較難解決的問題變成規模較小、易解決的同一問題,需要通過哪些步驟或等式來實現?這是解決遞歸問題的難點。把這些步驟或等式確定下來。
把以上三個方面分析好之後,就可以在子程序中定義遞歸調用。其一般格式為:
if 邊界條件 1 成立 then
賦予邊界值 1
【 elseif 邊界條件 2 成立 then
賦予邊界值 2
┇ 】
else
調用解決問題的通式
endif
例 1 : 計算勒讓德多項式的值
x 、 n 由鍵盤輸入。
分析: 當 n = 0 或 n = 1 時,多項式的值都可以直接求出來,只是當 n > 1 時,才使問題變得復雜,決定問題復雜程度的參數是 n 。根據題目提供的已知條件,我們也很容易發現,問題的邊界條件及邊界值有兩個,分別是:當 n = 0 時 P n (x) = 1 和當 n = 1 時 P n (x) = x 。解決問題的通式是:
P n (x) = ((2n - 1)P n - 1 (x) - (n - 1)P n - 2 (x)) / n 。
接下來按照上面介紹的一般格式定義遞歸子程序。
function Pnx(n as integer)
if n = 0 then
Pnx = 1
elseif n = 1 then
Pnx = x
else
Pnx = ((2*n - 1)*Pnx(n - 1) - (n - 1)*Pnx(n - 2)) / n
endif
end function
例 2 : Hanoi 塔問題:傳說印度教的主神梵天創造世界時,在印度北部佛教聖地貝拿勒斯聖廟里,安放了一塊黃銅板,板上插著三根寶石針,在其中一根寶石針上,自下而上地放著由大到小的 64 個金盤。這就是所謂的梵塔( Hanoi ),如圖。梵天要求僧侶們堅持不渝地按下面的規則把 64 個盤子移到另一根針上:
(1) 一次只能移一個盤子;
(2) 盤子只許在三根針上存放;
(3) 永遠不許大盤壓小盤。
梵天宣稱,當把他創造世界之時所安放的 64 個盤子全部移到另一根針上時,世界將在一聲霹靂聲中毀滅。那時,他的虔誠的信徒都可以升天。
要求設計一個程序輸出盤子的移動過程。
分析: 為了使問題更具有普遍性,設共有 n 個金盤,並且將金盤由小到大依次編號為 1 , 2 ,…, n 。要把放在 s(source) 針上的 n 個金盤移到目的針 o(objective) 上,當只有一個金盤,即 n = 1 時,問題是比較簡單的,只要將編號為 1 的金盤從 s 針上直接移至 o 針上即可。可定義過程 move(s,1,o) 來實現。只是當 n>1 時,才使問題變得復雜。決定問題規模的參數是金盤的個數 n ;問題的邊界條件及邊界值是:當 n = 1 時, move(s,1,o) 。
當金盤不止一個時,可以把最上面的 n - 1 個金盤看作一個整體。這樣 n 個金盤就分成了兩個部分:上面 n - 1 個金盤和最下面的編號為 n 的金盤。移動金盤的問題就可以分成下面三個子問題(三個步驟):
(1) 藉助 o 針,將 n - 1 個金盤(依照上述法則)從 s 針移至 i(indirect) 針上;
(2) 將編號為 n 的金盤直接從 s 針移至 o 針上;
(3) 藉助 s 針,將 i 針上的 n - 1 個金盤(依照上述法則)移至 o 針上。如圖
其中第二步只移動一個金盤,很容易解決。第一、第三步雖然不能直接解決,但我們已經把移動 n 個金盤的問題變成了移動 n - 1 個金盤的問題,問題的規模變小了。如果再把第一、第三步分別分成類似的三個子問題,移動 n - 1 個金盤的問題還可以變成移動 n - 2 個金盤的問題,同樣可變成移動 n - 3 ,…, 1 個金盤的問題,從而將整個問題加以解決。
這三個步驟就是解決問題的通式,可以以過程的形式把它們定義下來:
hanoi(n - 1,s,o,i)
move(s,n,o)
hanoi(n - 1,i,s,o)
參考程序如下:
declare sub hanoi(n,s,i,o)
declare sub move(s,n,o)
input "How many disks?",n
s = 1
i = 2
o = 3
call hanoi(n,s,i,o)
end
sub hanoi(n,s,i,o)
rem 遞歸子程序
if n = 1 then
call move(s,1,o)
else
call hanoi(n - 1,s,o,i)
call move(s,n,o)
call hanoi(n - 1,i,s,o)
endif
end sub
sub move(s,n,o)
print "move disk";n;
print "from";s;"to";o
end sub