有两个序列a,b, 大小都为n, 序列元素的值为任意整型数,无序;
要求:通过交换a,b中的[序列a元素的和]与[序列b元素的和]之间的差最小。
我的解答:
最后的解答结果都是我见到的测试方法,此方法本质上是穷举法,必然是最优解答。
在递归函数里保存列表is_used(用来保存某个元素是否已经用过了)的时候,一定要注意用copy.deepcopy.
不然保存的所有列表都是[0,0,0,.....], 因为如果不用前叙的方法的话, append()的是所有list的引用,而所有的这些引用指向的是同一个list对象,所以所有的子序列都一样,而这个序列最后返回到了初试状态,都是0,切记切记!
# it can be seen as a computation problem,
# so use un-repeatible enumerate method to find the best result
import copy
# test suit
# au: thomas will lee, lzj,
# new = [1, 2, 3, 4, 5, 6, 700, 800] # my 97 91, better than 99
new = [93, 91, 90, 82, 81, 74, 74, 74, 74, 68]
# store_dict = {min_difference: []}
# new = [1, 50, 90, 100, 10000, 10001] # my 38, 38, worth than 40
# new = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # 1 , 1 ;1
# new = [1, 1, 2, 3, 29, 30, 210, 232, 12311, 12312] # abs(-19)= 19 ,17, better than 21
# min_custom_enumerate(new)
sub_len = len(new) / 2
# to enumerate numbers in the list new
# a_iter = [0 for i in xrange(sub_len)]
# record whether one element is used
is_used = [0 for i in xrange(len(new))]
median = len(new) / 2
# use a list as a stack to store all scenarios
# sf = open('store_file','w')
# min_custom_enumerate_recursive(0)
all_list = []
def min_custom_enumerate_recursive(k):
if k == sub_len:
all_list.append(copy.deepcopy(is_used))
# min_recode()
# all_list.append(a_iter)
# sf.write(str(is_used))
# all_list += is_used
else:
for i in xrange(len(new)):
if not is_used[i]:
# all_list.append(is_used)
# a_iter[k] = new[i]
is_used[i] = 1 # used
min_custom_enumerate_recursive(k + 1)
is_used[i] = 0 # after the recursion backtracks
def solve():
# len(new) is always even
min_custom_enumerate_recursive(0)
# with open("store_file") as ff:
# # c = 1
# str(ff.readlines())
# print all_list
min_difference = abs(sum(new[:median]) - sum(new[median:]))
# min_difference = 1000000000000
all_list_len = len(all_list)
final_a = []
final_b = []
for line in all_list:
line_a = [new[i] for i in xrange(len(line)) if line[i] == 1]
line_b = [new[i] for i in xrange(len(line)) if line[i] == 0]
# print 'line_a',line_a
# print 'line_b',line_b
# print line_b
line_a_sum = sum(line_a)
line_b_sum = sum(line_b)
new_difference = abs(line_a_sum - line_b_sum)
if new_difference < min_difference:
min_difference = new_difference
final_a = copy.deepcopy(line_a)
final_b = copy.deepcopy(line_b)
print 'smallest value is', min_difference
print 'a', final_a
print 'b', final_b
solve()