假設所有的數字是正整數,這是可以做到的Yexo指出:
local n = 100
local t = {86, 23, 19, 8, 42, 12, 49}
local max_terms = 4
-- best[subset_size][terms][k] = {abs_diff, expr}
local best = {[0] = {}}
for k = 1, n do best[0][k] = {k, ''} end
for terms = 0, max_terms do best[terms] = best[0] end
for subset_size = 1, #t do
local new_best = {}
for terms = subset_size == #t and max_terms or 0, max_terms do
new_best[terms] = {}
for k = subset_size == #t and n or 1, n do
local b0 = best[terms][k]
local diff = k - t[subset_size]
local b1 = terms > 0 and (
diff > 0 and {
best[terms-1][diff][1],
best[terms-1][diff][2]..'+'..t[subset_size]
} or {math.abs(diff), t[subset_size]}
) or b0
new_best[terms][k] = b1[1] < b0[1] and b1 or b0
end
end
best = new_best
end
local expr = best[max_terms][n][2]:match'^%+?(.*)'
print((loadstring or load)('return '..expr)()..' = '..expr)
-- Output
99 = 23+19+8+49
[?揹包(http://en.wikipedia.org/wiki/Knapsack_problem) – 2013-03-26 19:32:28
在正常揹包問題您選擇的物品的最大數量不受限制,而在您的問題中似乎有四個限制。我仍然會使用與0/1揹包(動態編程)相同的方法。通過這種方法,你可以用'O(4nL)'來解決它,只要你獲得超過幾件物品,速度就會快很多。 – Yexo 2013-03-26 19:56:17
如果窮舉搜索算法速度太慢,請嘗試**分支並綁定**,這樣您就可以忽略大量子集而不嘗試它們。閱讀第13章http://www.statslab.cam.ac.uk/~rrw1/mor/s2010a4.pdf – 2013-03-26 21:09:21