有两个序列a,b,大小都为n,序列元素的值任意整数,无序;要求:通过交换a,b 中的元素,使[序列a 元素的和]与[序列b 元素的和]之间的差最小。

例如: var a = [100,99,98,1,2, 3]; var b = [1, 2, 3, 4,5,40];

最后的结果为: var a = [1,99,98,1,2,2]; var b = [100, 3,3,4,5,40];

思路一: 首先先计算a,b中元素和之间的差绝对值ABDis,然后逐一的把a中的元素和b中的任一元素作比较,如果它们交换后的差值绝对值ABTempDis小于原来的值ABDis,那么就把a,b交换,并重新计算a和b的绝对值,这种动作反复的进行,直到a中任一的元素都不能和b中的任一元素交换为止。(其实是穷举法)

思路二: 当前数组a和数组b的和之差为A = sum(a) - sum(b),a的第i个元素和b的第j个元素交换后,a和b的和之差为 A’ = sum(a) - a[i] + b[j] - (sum(b) - b[j] + a[i]) = sum(a) - sum(b) - 2 (a[i] - b[j]) = A - 2 (a[i] - b[j]) 设x = a[i] - b[j],那么 A’ = |A - 2x|,当然A’ 越小也好,所以当x 在 (0,A)之间时,做这样的交换才能使得交换后的a和b的和之差变小,x越接近A/2效果越好,如果找不到在(0,A)之间的x,则当前的a和b就是答案。 所以算法大概如下:在a和b中寻找使得x在(0,A)之间并且最接近A/2的i和j,交换相应的i和j元素,重新计算A后,重复前面的步骤直至找不到(0,A)之间的x为止。

#思路是有等长的两个列表a,b;a,b组成一个大列表_list然后从大到小排序;求出列表a,b各自的和s1,s2,然后比较;如果s1,s2的差值大于_list中的最大值,那么列表和小的就加上这个最大值,而列表和大的就加上_list的最小值;如果s1,s2的差值小于_list中的最大值,那么列表和小的就加上这个最大值,而列表和大的就加上_list的次大值;

a = [1,2,3,4,5,6,7];
b = [8,9,11,1,33,4,5,6];

source = a + b
source.sort(reverse=True)
print source

while True:
    s1,s2 = sum(m1),sum(m2)
    if s1 > s2:
        if s1 - s2 >= source[0]:
            m2.append(source.pop(0) if len(source) >=1 else 0)
            m1.append(source.pop() if len(source) >=1 else 0)
        else:
            m2.append(source.pop(0) if len(source) >=1 else 0)
            m1.append(source.pop(0) if len(source) >=1 else 0)
    else:
        if s2 - s1 >= source[0]:
            m1.append(source.pop(0) if len(source) >=1 else 0)
            m2.append(source.pop() if len(source) >=1 else 0)
        else:
            m1.append(source.pop(0) if len(source) >=1 else 0)
            m2.append(source.pop(0) if len(source) >=1 else 0)
    print m1,m2
    if len(source) == 0:
        break
print sum(m1)-sum(m2)