您的方法不起作用的测试用例是
que = [1, 1, 50, 50, 50, 1000]
问题是您要成对分析事物,在此示例中,您希望所有 50 人都在同一个组中。如果您删除配对分析方面并且一次只输入一个条目,这应该可以解决。
这是执行此操作的代码
def make_teams(que):
que.sort()
que.reverse()
if len(que)%2: que.insert(0,0)
t1,t2 = [],[]
while que:
if abs(len(t1)-len(t2))>=len(que):
[t1, t2][len(t1)>len(t2)].append(que.pop(0))
else:
[t1, t2][sum(t1)>sum(t2)].append(que.pop(0))
print min(sum(t1),sum(t2)), max(sum(t1),sum(t2)), "\n"
if __name__=="__main__":
que = [2,3,10,5,8,9,7,3,5,2]
make_teams(que)
que = [1, 1, 50, 50, 50, 1000]
make_teams(que)
这给出了 27、27 和 150、1002,这对我来说是有意义的答案。
编辑:在审查中,我发现这实际上不起作用,但最后,我不太确定为什么。不过,我会在这里发布我的测试代码,因为它可能有用。该测试仅生成具有相等总和的随机序列,将它们放在一起并进行比较(结果令人遗憾)。
编辑#2:根据 Unknown, 指出的示例[87,100,28,67,68,41,67,1]
,很清楚为什么我的方法不起作用。具体来说,要解决这个例子,需要将两个最大的数字都添加到同一个序列中以获得有效的解决方案。
def make_sequence():
"""return the sums and the sequence that's devided to make this sum"""
while 1:
seq_len = randint(5, 200)
seq_max = [5, 10, 100, 1000, 1000000][randint(0,4)]
seqs = [[], []]
for i in range(seq_len):
for j in (0, 1):
seqs[j].append(randint(1, seq_max))
diff = sum(seqs[0])-sum(seqs[1])
if abs(diff)>=seq_max:
continue
if diff<0:
seqs[0][-1] += -diff
else:
seqs[1][-1] += diff
return sum(seqs[0]), sum(seqs[1]), seqs[0], seqs[1]
if __name__=="__main__":
for i in range(10):
s0, s1, seq0, seq1 = make_sequence()
t0, t1 = make_teams(seq0+seq1)
print s0, s1, t0, t1
if s0 != t0 or s1 != t1:
print "FAILURE", s0, s1, t0, t1