- 论坛徽章:
- 0
|
思路:
合并两个列表,排序,然后按顺序从后往前每次取两个元素a, b,则a >= b
将取出来的数按a-b的值b进行分组
将分组按a-b的值排序然后合并,得到一个长为n的列表listab = [(a1,b1), (a2,b2), (a3,b3), ..., (an,bn)]
可证(listab[0] - listab[1]) >= (listab[i-1][0] - listab[i-1][1]) (0<= i < n)
定义两个空序列lista, listb
然后按从后往前的顺序取出listab的值并根据sum(lista)-sum(listb)的值,将ai,bi压入数组lista或listb
压入第一个时,abs(sum(lista) - sum(listb))最大,然后逐渐减小。
这个算法简单,实现也简单,思考5分钟,代码3-5分钟。- def min_sub_of_sum(lista, listb):
- listab = lista + listb
- listab.sort()
- tmp = {}
- while listab:
- a = listab.pop()
- b = listab.pop()
- tmp.setdefault(a-b, []).append((a, b))
- subs = tmp.keys()
- subs.sort()
- for sub in subs:
- listab.extend(tmp[sub])
- lista, listb = [], []
- # sub == sum(lista) - sum(listb)
- sub = 0
- while listab:
- if sub < 0:
- a, b = listab.pop()
- else:
- b, a = listab.pop()
- lista.append(a)
- listb.append(b)
- sub += (a - b)
- return lista, listb
- if __name__ == '__main__':
- lista = range(100)
- listb = [i^11 for i in lista]
- a, b = min_sub_of_sum(lista, listb)
- print a
- print b
- print sum(a) - sum(b)
复制代码 |
|