C/C++类似于子集和的算法的实现
这个问题比背包(或其一种类型,没有值,只有正权重)更简单。该问题包括检查一个数字是否可以是其他数字的组合。该函数应返回 true
或 false
。
例如,
112 和具有 { 17, 100, 101 }
的列表应返回 false
,具有相同列表的 469
应返回 true
、35
应返回 false
、119
应返回 true
等...
编辑:子集和问题比背包问题更准确。
The problem is simpler than knapsack
(or a type of it, without values and only positive weights). The problem consists of checking whether a number can be a combination of others. The function should return true
or false
.
For example,
112 and a list with { 17, 100, 101 }
should return false
, 469
with the same list should return true
, 35
should return false
, 119
should return true
, etc...
Edit: subset sum problem would be more accurate for this than knapsack.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是子集和问题的一种特殊情况,其中的集合仅包含一个负数(即,将 112 和 { 17, 100, 101 } 表示为 { -112, 17, 100, 101 })。维基百科页面上有一些算法,http://en.wikipedia.org/wiki/Subset_sum_problem。
This is a special case of the Subset Sum problem, with sets that only contain one negative number (i.e., express 112 and { 17, 100, 101 } as { -112, 17, 100, 101 }). There's a few algorithms on the Wikipedia page, http://en.wikipedia.org/wiki/Subset_sum_problem.
对您有帮助的观察是,如果您的列表是 {a, b, c...} 并且您要测试的数字是 x,则仅当 x 或 xa 可以时,x 才能写为子列表的和写为子列表 {b, c, ...} 的和。这使您可以编写一个非常简单的递归算法来解决问题。
编辑:这是一些代码,考虑到下面的评论。未经测试,因此可能有错误;并且不一定是最快的。但对于小型数据集,它可以很好地完成工作。
An observation that will help you is that if your list is {a, b, c...} and the number you want to test is x, then x can be written as a sum of a sublist only if either x or x-a can be written as a sum of the sublist {b, c, ...}. This lets you write a very simple recursive algorithm to solve the problem.
edit: here is some code, taking into account the comments below. Not tested so probably buggy; and not necessarily the fastest. But for a small dataset it will get the job done neatly.
请注意,随着查询数量变大,正结果会变得更密集。例如,所有大于 100^2 的数字都可以通过 { 17, 100, 101 } 生成。因此,最佳算法可能取决于查询的数量是否远大于集合的成员。您可能会研究一下场论。
至少,您知道如果该集合的最大公约数不在查询中,则结果始终为假,并且可以在可忽略不计的时间内进行检查。
Note that positive results become denser as the queried number becomes larger. For example, all numbers greater than 100^2 can be generated by { 17, 100, 101 }. So the optimal algorithm may depend upon whether the queried number is much greater than the set's members. You might look into field theory.
At the least, you know the result is always false if the greatest common divisor of the set is not in the query, and that can be checked in negligible time.
如果要到达的数字不太大,您可能可以从集合中生成落在 [1,N] 范围内的所有可到达数字。
问题:使用列表
L
中的元素达到N
,其中N
足够小,不必担心大小为N 的向量
元素的大小。算法:
N
的向量V
L
中的每个元素l
V
中的每个可达元素v
v + n*l
标记为可达If the number to reach is not too large, you can probably generate all the reachable numbers from the set that fall in the range [1,N].
Problem: Reach
N
using the elements in the listL
, whereN
is small enough not to worry about a vector of sizeN
elements' size.Algorithm:
V
of sizeN
l
in the listL
v
inV
v + n*l
in V as reachable