Диапазон сумм и количество элементов выглядят слишком большими для динамического c программирования из-за недостатка памяти.
Но ограничение в 40 элементов позволяет применить что-то вроде принцип «встречи посередине» .
Разделите первые 20 элементов и подсчитайте суммы для всех возможных подмножества - просто пройдите через 2 ^ 20 подмножеств (включая пустой!) (используя рекурсию или двоичное представление номера подмножества или каким-либо другим способом) и запишите суммы на карту, содержащую пары (sum, count)
.
Проделайте то же самое для второй половины. Обратите внимание, что размер карт достаточно надежен.
Пройдитесь по первым ключам карты и найдите соответствующие ключи на второй карте. Псевдокод:
for sum in map1:
if map2.contains(X - sum):
result += map1[sum] * map2[X - sum]