我有几个数字数组(数组的每个元素只能取值0或1),如下所示
v1: 1; 0; 0; 1; 1; v2: 0; 1; 0; 0; 1; v3: 1; 1; 0; 1; 0; v4: 1; 0; 0; 1; 0; v5: 1; 1; 0; 1; 1; v6: 1; 1; 0; 1; 1;
我希望找到这样的子集,当数组求和时,结果数组的单个元素是2的倍数。例如,v1 + v2 + v3得到的结果数组为2,2,0,2, 2.结果数组可以具有2的倍数值。
另一个例子:
v1: 1, 1, 1, 0, 1, 0 v2: 0, 0, 1, 0, 0, 0 v3: 1, 0, 0, 0, 0, 0 v4: 0, 0, 0, 1, 0, 0 v5: 1, 1, 0, 0, 1, 0 v6: 0, 0, 1, 1, 0, 0 v7: 1, 0, 1, 1, 0, 0
在此示例中,v1 + v2 + v5和v3 + v6 + v7是合适的答案。
我有一个强力解决方案,但我想检查是否有更有效的方法。这相当于子集求和问题吗?
答案 0 :(得分:1)
您想找到所有解决方案吗?
这可以找到一个解决方案(我认为可以扩展它以找到所有解决方案)。
将每个数组表示为二进制数。
因此v1变为10011,v2变为01001等。
设*表示按位mod 2加法。
e.g。
v1*v2*v3 = 00000
所以我们的目标是找到mod 2加法全为零的数组。 让你和v成为任何二进制数。 然后u * v = 0 iff u = v。
e.g。
(v1*v2)*v3 = 0
v1*v2 = 11010 = v3.
如果你* v = w那么
u*v*v = w*v, so
u*0 = w*v,
u = w*v
所以我们可以从0开始进行反向搜索。假设最后一组数组包含v。然后v * T = 0,其中T是一些二进制数。我们有T = 0 * v。如果T是给定数组之一,那么我们就完成了。否则我们从T开始继续搜索。
这在下面正式描述。
每个州都是二进制数。
设0为初始状态。
给定的数组是状态空间的一部分,比如S。
我们的目标状态是S中的任何元素。
令T为和为0的数组的必需子集。
在每个州,让任何不在T的州都可以采取行动。
每次操作后都将数组用于T。
如果在任何非目标阶段S = T,那么就没有解决方案。
现在我们可以在这个空间运行DFS来找到解决方案。