Будем использовать целое число в качестве битового массива. Бит установлен, если сумму равную номеру бита можно составить из чисел списка. Битовый массив обновляется с помощью логических операций.
Пусть битовый массив bits
хранит текущие возможные суммы, а v
- новое значение. Тогда bits | (bits << v)
представляет возможные суммы с учетом прибавления нового значения. В коде используется более сложное выражение с использованием маски, чтобы в результат не попадали биты с номерами больше target
. Начальное значение для bits
- единица, что означает нулевую сумму. Номер старшего бита в конце вычисляется с помощью метода bit_length()
.
Код укладывается в полсекунды:
import pprint
import random
n = int(input())
a = tuple(random.randint(1, 1000000) for _ in range(n))
sum_a = sum(a)
print('random list')
pprint.pprint(a, compact=True)
print('random list sum', sum_a)
target = sum_a // 2
print('target', target)
mask = (1 << (target + 1)) - 1
bits = 1
for v in a:
bits |= (bits & (mask >> v)) << v
best = bits.bit_length() - 1
print('best result', best)
print('diff', sum_a - 2 * best)
$ time echo 100 | python best-half-sum.py
random list
(774463, 428203, 965459, 818122, 193575, 281900, 888202, 463588, 843773, 745292,
364132, 133468, 894830, 119204, 413031, 2747, 848141, 555223, 511840, 157509,
984794, 533463, 77229, 865676, 353186, 913647, 855883, 315587, 593910, 726941,
729062, 399663, 213904, 359355, 890092, 52267, 105879, 168716, 373423, 231081,
595450, 17507, 844313, 765630, 531597, 721180, 29680, 664959, 784327, 656553,
74145, 837963, 454037, 357505, 667483, 421984, 453216, 979355, 505268, 932855,
483589, 19503, 39389, 129525, 605585, 467242, 245845, 89485, 351318, 751965,
639115, 693835, 401083, 414712, 212093, 366859, 243789, 123832, 679784, 942795,
789211, 907654, 799522, 398138, 555322, 664031, 665411, 794290, 837955, 822544,
640505, 580149, 598882, 333417, 491232, 245162, 7552, 932056, 50860, 217223)
random list sum 50673926
target 25336963
best result 25336963
diff 0
real 0m0.440s
user 0m0.364s
sys 0m0.072s