すべての数値が正の整数であると仮定すると、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