問題一:3010 種
問題二:21607 種
以下是 php 程式:
<pre class="c" name="code">$kind=0;
ccc(30,27);
echo "27 kind={$kind}\n";
$kind=0;
ccc(30,37);
echo "37 kind={$kind}\n";
function ccc($max, $value)
{
global $kind;
if ($max > 0 && $value > 0)
{
$a = $value % $max;
$b = (int)floor($value / $max);
if ($max > 1 && $a > 0)
ccc($max-1, $a);
else
$kind++;
for ($i=$b-1; $i>=0; $i--)
{
$d[$max] = $i;
ccc($max-1, $value-($i*$max));
}
}
}
if ($max > 0 && $value > 0)
{
您的算法好像變成排列,而非組合
如1-3元錢幣要算3元有幾總組合
其組合有
111
12
3
三種,但您的演算法會有6種,變成排列了。
php.exe -n ccc.php
3元幣=1個
2元幣=1個, 1元幣=1個
1元幣=3個
total=3
抱歉 $kind++ 沒歸零,所以驗證有誤
是否有其他演算法,如樹狀或統計函數,讓執行效率提高?
dynamic programming
沒錯,用 dp 可以加快百倍以上的速度,樓主可以試試將小弟的 function 改為 dp 版本,即可知效果。
我自己以 dp 改寫後,測試 ccc(30,27)到ccc(30,77) 的結果。
原始函式的時間遞增得相當快,而動態規劃則變動很小。
<pre class="c" name="code">ccc(30, 27)原始函式:quantity=3010 time:0.01195502281189
ccc(30, 27)動態規劃:quantity=3010 time:0.0011961460113525
ccc(30, 37)原始函式:quantity=21607 time:0.09086799621582
ccc(30, 37)動態規劃:quantity=21607 time:0.001121997833252
ccc(30, 47)原始函式:quantity=123839 time:0.54752492904663
ccc(30, 47)動態規劃:quantity=123839 time:0.0013818740844727
ccc(30, 57)原始函式:quantity=602422 time:2.803258895874
ccc(30, 57)動態規劃:quantity=602422 time:0.0016791820526123
ccc(30, 67)原始函式:quantity=2580573 time:12.635329008102
ccc(30, 67)動態規劃:quantity=2580573 time:0.0019540786743164
ccc(30, 77)原始函式:quantity=9974703 time:51.097416877747
ccc(30, 77)動態規劃:quantity=9974703 time:0.0023171901702881
小弟用C#照 wiseguy大大的函式去跑,
ccc(12, 12)要35秒,
ccc(47, 47)超過30分鐘後都沒反應,只好中止,
還在找瓶頸在哪,原先想說用Threading去跑個別遞迴....
dp是不錯的解決方式
PS.電腦是ASUS B121平板/RAM 4G/OS windows 8 / VS 2010
樓主是不是弄錯了什麼了?我用 php 跑,不管 ccc(12,12) 還是 ccc(47,47) 都不到一秒,C# 怎麼可能比 php 這種 script 語言還慢?我的電腦也只是 Core Duo E7200 2.53GHz + 3GB RAM,平板有差這麼多嗎?
<pre class="c" name="code">ccc(12, 12)原始函式:quantity=77 time:0.019269943237305
ccc(12, 12)動態規劃:quantity=77 time:0.00022411346435547
ccc(47, 47)原始函式:quantity=124754 time:0.51868987083435
ccc(47, 47)動態規劃:quantity=124754 time:0.0037131309509277
我也覺得很納悶。
抓出兇手了,因一個紀錄顯示變數值的TextBox造成的問題,拿掉後就正常了,
只是時間還有點長ccc(50, 50)跑了21秒,不過比之前要快太多了。
齁~ 原來樓主用 GUI 啊~ 難怪我說奇怪,C# 怎麼可能是這種速度?
這種演算法的東西,用 console 模式寫比較準啦~
要不然光是 GUI 處理就耗掉不少時間了
我覺得加上GUI也不應該那麼慢吧
我用C寫(50, 50)也是瞬間出來 GUI有吃那麼重嗎@@?
複雜度也只有(coin數*目標值)而已吧
是說這題我覺得dp還比較簡單 遞迴我反而還要想0.0"
對啊!加上GUI也不應該那麼慢。別說用 C 了,我用 javascript 在網頁跑遞迴,(50,50)也是瞬間就跑完了。要超過10秒的,至少得算 70 元以上。不過這是不做 dp 的結果。改成 dp 跑 (70,70) 也花不到 0.1 秒。
這種題目用遞迴解,只需不到20行程式就解完了,dp是避免它重覆遞迴已經遞迴過的改善措施。所以小弟不明白 carl830 所言《dp還比較簡單 遞迴我反而還要想》,意思是您不是用遞迴解的嗎?不用遞迴的話,程式碼不少喔?