Algorithm 使用约束拆分子集
今天,在练习一些算法问题时,我发现了一个有趣的问题。 问题是 您必须将1除以Algorithm 使用约束拆分子集,algorithm,subset-sum,Algorithm,Subset Sum,今天,在练习一些算法问题时,我发现了一个有趣的问题。 问题是 您必须将1除以n(缺少一个x)为两个相等的值 使两个半之和相等的半 例如: 如果n=7和x=4 解决方案将是{7,5}和{1,2,3,6} 我可以用蛮力的方法来回答,但我想要一个有效的解决方案 有人能帮我吗?如果元素之和为1→没有x的N是奇数,那么就没有解 否则,您可以在O(N)中找到平衡选择的解决方案 连续四个 首先让我们考虑任何四个连续数的序列可以在两个集合中以相等的和而被划分为: [x,x+1,x+2,x+3]→ [x+3,x]
n
(缺少一个x
)为两个相等的值
使两个半之和相等的半
例如:
如果n=7
和x=4
解决方案将是{7,5}
和{1,2,3,6}
我可以用蛮力的方法来回答,但我想要一个有效的解决方案
有人能帮我吗?如果元素之和为1→没有x的N是奇数,那么就没有解 否则,您可以在O(N)中找到平衡选择的解决方案 连续四个
首先让我们考虑任何四个连续数的序列可以在两个集合中以相等的和而被划分为:
[x,x+1,x+2,x+3]→ [x+3,x];[x+2,x+1] 因此,选择它们并将它们放入集合A B A平衡集合A和集合B 4对面 此外,当我们在一个省略的值上有两对夫妇时,它可以具有类似的属性: [x-2,x-1,x+1,x+2]→ [x+2,x-2];[x+1,x-1] 所以还是个B 此时,我们可以修复以下情况:- 我们有一个四胞胎:我们像案例1一样分割它
- 我们有两个数字,x和其他两个数字:我们像案例2那样拆分
11 10 9 8 7 6 5 4 3 2 1
总和是偶数,因此x只能是偶数:
x = 10
11 - 9 | 8 7 6 5 | 4 3 2 1 → (+2 gap - on A) (4 in a row) (balancing tail)
A B A B B A B A B A
x = 8
11 10 | 9 - 7 | 6 5 | 4 3 2 1 → (4 across +) (+2 gap - on A) (balancing tail)
a b A B | b a | B A B A
x = 6
11 10 9 8 | 7 - 5 | 4 3 2 1 → (4 in a row) (+2 gap - on A) (balancing tail)
A B B A A B A B B B
x = 4 we have no balancing tail - we have to do that with head
11 10 9 8 | 7 6 | 5 - 3 | 2 1 → (balancing head) (4 across +) (+2 gap)
A B A B A B | b a | B A
x = 2
11 10 9 8 | 7 6 5 4 | 3 - 1 → (balancing head) (4 in a row) (+2 gap)
A B A B A B B A B A
注意到解的对称性是很有趣的。另一个例子
10 9 8 7 6 5 4 3 2 1
总和是奇数,所以x只能是奇数,现在元素的数目是奇数
x = 9
10 - 8 | 7 6 5 4 | 3 2 1 → (+2 gap - on A) (4 in a row) (balancing tail)
A B A B B A B A B
x = 7
10 9 | 8 - 6 | 5 4 | 3 2 1 → (4 across +) (+2 gap - on A) (balancing tail)
a b | A B | b a B A B
x = 5
10 9 8 7 | 6 - 4 | 3 2 1 → (4 in a row) (+2 gap - on A) (balancing tail)
A B B A A B B A B
x = 3
10 9 8 7 | 6 5 | 4 - 2 | 1 → (balancing head) (4 across + virtual 0) (+2 gap)
A B A B B A | a b | A
x = 1
10 9 8 7 | 6 5 4 3 | 2 → (balancing head) (4 in a row) (+2 gap virtual 0)
A B A B A B B A B
最后值得注意的是,只要我们有一个完整的平衡段(即一行4个或四个交叉段),我们就可以从A切换到B
有趣的是,如果您自己尝试,那么请求求和([1…N]-x)的属性甚至会使案例变得非常冗余
我很确定这个算法可以推广——我可能很快就会提供一个修订版。这个问题可以通过将动态规划的标准与预处理步骤结合起来来解决。这些步骤是O(1)com的步骤 算法(n,x):
def subsetsum(arr, i, sum, ss):
if i >= len(arr):
if sum == 0:
print ss
return 1
else:
return 0
ss1 = ss[:]
count = subsetsum(arr, i + 1, sum, ss1)
ss1.append(arr[i])
count += subsetsum(arr, i + 1, sum - arr[i], ss1)
return count
arr = [1, 2, 3, 10, 5, 7]
sum = 14
a = []
print subsetsum(arr, 0, sum, a)
希望有帮助 您应该检查是否能够达到(和(1到n)-x)/2。数字不包括x。它与子集合总和相同。n=7和x=4的答案也是[7,5],[1,2,3,6]Thanx,我纠正了这个错误。我没有试图证明它,但可能贪婪算法总是有效的(如果有解决方案的话)。你应该花些时间来研究这个方向。你能提供一些参考来更好地研究这个解决方案吗