程式設計之美讀書筆記
221.1624
點遊戲給定
4個數,能否只通過加減乘除計算得到
24?由於只有
4個數,弄個多重迴圈,就可以。如果要推廣到
n個數,有兩種思路:
①採用字首
/字尾表示式。相當於將
n個數用
n-1個括號括起來,其數目就是乙個
catlan
數。最多可得到
f(n) = (1/n * (2*n - 2)! / (n-1)! / (n-1)!) * n! * 4^(n-1) = 4^(n-1) * (2*n-2)! / (n-1)!
種表示式,當
n=4時,共可得到
7680種。②
從n個數中任意抽取
2個,進行計算最多有
6種結果,將計算結果放回去,再從剩下的
n-1個任取
2個,進行計算,如此反覆,直到只剩下
1個數。按這種演算法,共要處理表示式:
g(n)=(n*(n-1)/2*6) * ((n-1)*(n-2)/2*6) * ((n-2)*(n-3)/2*6) * (2*1/2*6) = n!*(n-1)!*3^(n-1)
當n=4
時,最多要處理
3888種。(
書上的**將這兩種思路混在一塊了。)
f(n) / g(n) = (4/3)^(n-1) * (2*n-2)! / n! / (n-1)! / (n-1)!
很明顯,當
n比較大時(比如n大於
8),會有
f(n) < g(n)
。比如:
f(10)/g(10)=0.178。從
f(n)
與g(n)
的比值,可以看出,這兩種解法都存在大量的不必要計算。當
n比較大時,思路
2的冗餘計算已經嚴重影響了效能。要如何減少這些不必要計算呢?
可以記錄得到某個計算結果時所進行操作。比如
: a、b、
c和d這
4個數取前
2個,進行加法計算得到
a+b,則記錄『
+』。另外,假設加減號的優先順序為
0,乘除號的優先順序為1。
a和b進行減
/除計算時,實際上得到
a-b與
b-a,
a/b與
b/a。
當取出2個數a
和b,進行計算,這兩個數上次的操作符有下面這幾種情況:
①都為空:
要計算6
個結果,即
a+b, a-b, b-a, a*b, a/b, b/a。②
只有乙個為空:假設:
a = a1 op1 a2
⑴ 一種剪枝方法是:
若op1
為減(除)號,則不進行加減(乘除)計算。
因為:(a-b)-c
可以轉為
a-(b+c)
,這兩個表示式只要計算乙個就可以。
⑵ 另一種剪枝方法:額外記錄每次計算最靠後的那個數的位置。比如位置順序:a、
b、c、
d,進行
a+c計算時,記錄了
c位置,再與數
b計算時,由於
b位置在
c位置前,不允許計算
(a+c) + b
和(a+c) – b
這樣就避免了表示式
a+b+c
和a-b+c
被重複計算。
③都不為空:
假設:a = a1 op1 a2
,b= b1 op2 b2
要計算的結果:
a op3 b =
(a1 op1 a2
)op3 (b1 op2 b2)
⑴ 如果
op1
和op2
的優先順序相同,那麼
op3
的優先順序不能與它們相同,若相同,則原來的表示式可以轉為
((a1 op4 a2) op5 b1) op6 b2
,因而沒必要對原來的表示式進行計算。比如
(m1+m2)
與(m3-m4)
之間只進行乘除計算,而不進行加減計算。
⑵ 如果
op1
和op2
的優先順序不同,那麼
op3
無論怎麼取,其優先順序都必會與其中乙個相同,則原表示式可以轉化
((c1 op4 c2) op5 c3) op6 c4
這種形式,因而該表示式沒必要計算。如
(m1+m2)
與(m3*m4)
,不進行任何計算。
總之:op1
與op2
優先順序不同時,不進行計算。
op1
與op2
優先順序相同時,進行計算的操作符優先順序不與它們相同。
要注意的是:剪枝不一定提高效能(在筆記
1.3
一摞烙餅的排序 中已經說明了這個問題
)。如果
n個數計算可得到
24,過多的避免冗餘計算,有可能嚴重降低效能。計算
n=6時,碰到乙個組合,僅使用了③的剪枝方法,得到結果時處理了四百個表示式,但再採用了②的第一種剪枝方法,處理的表示式達到五十三萬多。(也許②的第二種剪枝方法不存在這麼嚴重的問題。)與烙餅排序不同的是,烙餅排序總能找到乙個結果,而
n個數計算有可能無解。顯然在無解時,採用盡可能多的剪枝方法,必然會極大的提高效能。
另外,對於輸出表示式,書上的程式進行了大量的字串操作,實際上可以只記錄,每一步取出的兩個數的位置(即記錄i、
j值),在需要輸出時,再根據所記錄的位置,進行相應的字串操作就可以了。
書上給出的另一種解法,通過記錄中間結果來減少冗餘計算。在
n比較小時,對效能改進影響不會太大;
n較大時,中間結果需要多少記憶體?是否會出現物理記憶體不足,而使程式效能極其低下呢?
下面的**是個半成品:
《程式設計之美》讀書筆記
程式設計之美 讀書筆記 一 中國象棋將帥問題 程式設計之美 讀書筆記 二 求二進位制數中1的個數 擴充套件問題 程式設計之美 讀書筆記 三 一摞烙餅的排序問題 程式設計之美 讀書筆記 四 買書折扣問題的貪心解法 程式設計之美 讀書筆記 五 飲料 問題 程式設計之美 讀書筆記 六 連連看遊戲設計 程式...
《程式設計之美》讀書筆記集錦
程式設計之美 讀書筆記 一 中國象棋將帥問題 程式設計之美 讀書筆記 二 求二進位制數中1的個數 擴充套件問題 程式設計之美 讀書筆記 三 一摞烙餅的排序問題 程式設計之美 讀書筆記 四 買書折扣問題的貪心解法 程式設計之美 讀書筆記 五 飲料 問題 程式設計之美 讀書筆記 六 連連看遊戲設計 程式...
《程式設計之美》讀書筆記集錦
程式設計之美 讀書筆記 一 中國象棋將帥問題 程式設計之美 讀書筆記 二 求二進位制數中1的個數 擴充套件問題 程式設計之美 讀書筆記 三 一摞烙餅的排序問題 程式設計之美 讀書筆記 四 買書折扣問題的貪心解法 程式設計之美 讀書筆記 五 飲料 問題 程式設計之美 讀書筆記 六 連連看遊戲設計 程式...