Если, как вы упомянули в своем комментарии, 10 - это наибольшее число в задаче (также максимальное количество элементов). Тогда грубая сила (с умной битовой маскировкой, см. этот урок ) сделает:
// N is the number of elements and arr is the array.
for (int i = 0; i < (1 << N); ++i) {
int sum = 0;
for (int j = 0; j < N; ++j) if (i & (1 << j)) sum += arr[j];
if (sum == required_sum); // Do something with the subset represented by i.
}
Этот алгоритм имеет сложность O (N * 2 ^ N). Обратите внимание, что код верен до тех пор, пока N <32. Обратите внимание, что количество подмножеств с определенной суммой может быть экспоненциальным (более 2 ^ (N / 2)). Пример, {1, 1, 1, 1, .., 1} и сумма = N / 2. </p>
Если, однако, N велико, но N * required_sum не очень велико (до миллионов), можно использовать следующее повторение (с динамическим программированием или запоминанием):
f(0, 0) = 1
f(0, n) = 0 where n > 0
f(k, n) = 0 where k < 0
f(k + 1, S) = f(k, S - arr[k]) + f(k, S) where k >= 0
где f (k, S) обозначает возможность получения суммы S с подмножеством элементов 0..k. Динамическая таблица программирования может использоваться для генерации всех подмножеств. Время генерации таблицы составляет O (N * S), где S - требуемая сумма. Время генерации подмножеств из таблицы пропорционально количеству таких подмножеств (которое может быть очень большим).
Общие замечания по проблеме:
Проблема в общем случае NP-Complete . Следовательно, он не имеет известного алгоритма полиномиального времени. Тем не менее, он имеет алгоритм псевдополиномиального времени , а именно повторение выше.