我们说我有一个名为数字的向量。 数字= {1,5,6,8}。 (我有一种可能性是将矢量的大小加倍并包括所有负数,但我仍然没有很好的解决方案来找到所有可能的总和。)
可能的解决方案:
4 = 5 - 1
1 = 1
19 = 8 + 6 + 5
我想在我找到一个我要找的号码时停止搜索,但我的主要问题是找到所有不同的总和。
这与子集和问题非常相似,但我还没有真正找到一个我能理解的解决方案/包含负数。
答案 0 :(得分:0)
使用动态编程。
让(a_0, ..., a_{n-1})
成为您的数字数组。
设A(k)
为(a_0, ..., a_{k-1})
的所有可能总和/差异的集合。
然后,您可以轻松地从A(k)
推断A(k-1)
。确保使用哈希表或排序或其他任何内容删除所有重复。
关键是,如果m
的上限为a_i
,则A(k)
最多包含2mk + 1
个元素。因此,复杂性从O(3^n)
减少到O(mn^2)
。
这可能是您可以做的最好的事情:例如,如果a_i
以指数方式增加,那么最终结果的大小也是指数级的。
答案 1 :(得分:0)
在三元表示{0,1,2}中思考,你有一组数字,其中每个数字都可以显示为正数,负数或不显示,那么你可以将这个可能性表示为三元{0,1,2}并使用它与coef - > {-1,0,1}您可以轻松计算所有组合。 coef - > (-1,0,1) - >三元' 0' - >价值' -1',三元' 1' - >价值' 0'和三元2 - >价值' 1'。
Numbers -> {n0, n1, n2, .. ni}
三元表示 - > (t0)*3^0 + (t1)*3^1 + (t2)*3^2 + .. + (ti)*3^i
Coef - > {c0 , c1, c2, .. ci}
结果 - > C0*n0 + C1*n1 + C2*n2 + .. + Ci*ni
一个例子:
Numbers = {1, 5, 6, 8}
总组合 - > 3^4 = 81
组合数(c)∈[0,80]。
f.e:c = 79
- > 2221(ternary)
三元(反向){1, 2, 2, 2}
到coef {0, 1, 1, 1}
结果(79d / 2221t):0*1 + 1*5 + 1*6 + 1*8 = 19
要计算所有组合,您必须在循环(i -> 0 .. 3^4)