記一道毫無思路的演算法題

深藍發表於2014-10-23

今天賢內給了我一道很實際的演算法題,把我徹底難住了,實在想不出來,於是寫此博文以記之。

背景是這樣的,現在有一個付款明細的Excel,裡面有為哪個發票,哪個公司應付多少錢的明細,明細資料是62條,現在知道我們已經付出的金額為Sum,請問到底哪些發票是已付款的。

這是62條明細資料:

653165.00
356029.11
220896.45
146362.00
1847670.00
3018518.91
1347553.07
145010.74
339784.84
199350.28
1206114.00
882000.00
253246.13
720000.00
24194.07
1518952.00
139453.48
200415.00
812044.00
9032764.57
3960608.05
1855126.31
7409087.18
608094.66
225519.59
627912.23
109897.52
1215819.87
4220245.50
94299.00
96547.00
92616.01
597100.54
880440.00
343991.59
70468.19
1092418.47
66911.94
80138.65
1398551.14
172287.48
691097.86
2371693.44
3773148.63
83898.33
89922.75
2619220.46
1179477.63
3440250.98
700000.00
997545.00
272523.00
3009976.00
451891.44
2111314.00
306377.00
142329.00
2057178.00
9340.00
249027.00
60811.50
51188.50

付款的金額為:

35857936.42

這聽起來是一個很簡單的演算法題,其實就是算組合嘛,把每種組合的金額進行相加,如果等於Sum金額,那麼就輸出這種組合。於是網上找找組合函式的程式碼,很快就寫出了這個程式。而且使用了一些簡單的測試程式,確認計算是正確的。但是真正用到這個事情中,卻崩潰了,計算量太大,根本算不出來。

仔細一想,對於每個數字,要麼出現,要麼不出現,那麼其計算複雜度就是O(2^n),這裡n=62,那麼差不多就得計算2的62次,遍歷每一種組合,才能找到全部答案。天啊!2的62次方!

根本不可能完成啊。想了又想,怎麼都沒有想到好的辦法把複雜度降下來,傷心。不知道有沒有大神能夠解決這個問題。

這還只是一次資料,以後說不定還有100條明細,200條明細的,就這破演算法,那更是天文數字,怎麼可能算得出來啊?!

 附上現有的程式碼下載

 

更新:

好吧,看來我太無知了,這個問題是沒有解決辦法的,StackOverflow的討論:http://stackoverflow.com/questions/4355955/subset-sum-algorithm

而且還有專門的維基百科頁面:http://en.wikipedia.org/wiki/Subset_sum_problem#Pseudo-polynomial_time_dynamic_programming_solution 

相關文章