Подсчитайте способы разбить массив на два подмножества, разница между их суммой которых равна K

Опубликовано: 22 Сентября, 2022

Имея массив A[] размера N и целое число diff , задача состоит в том, чтобы подсчитать количество способов разбить массив на два подмножества ( возможно непустое подмножество ) так, что разница между их суммами равна diff .

Примеры:

Input: A[] = {1, 1, 2, 3}, diff = 1  
Output: 3  
Explanation: All possible combinations are as follows: 

  • {1, 1, 2} and {3}
  • {1, 3} and {1, 2}
  • {1, 2} and {1, 3}

All partitions have difference between their sums equal to 1. Therefore, the count of ways is 3.

Input: A[] = {1, 6, 11, 5}, diff=1
Output: 2

Наивный подход: самый простой подход к решению проблемы основан на следующих наблюдениях:

Let the sum of elements in the partition subsets S1 and S2 be sum1 and sum2 respectively.
Let sum of the array A[] be X
Given, sum1 – sum2 = diff – (1)
Also, sum1 + sum2 = X – (2)

From equations (1) and (2), 
sum1 = (X + diff)/2

Поэтому задача сводится к нахождению количества подмножеств с заданной суммой.
Поэтому самый простой подход к решению этой проблемы состоит в том, чтобы сгенерировать все возможные подмножества и проверить, имеет ли подмножество требуемую сумму.

Временная сложность: O(2 N )
Вспомогательное пространство: O(N)

Эффективный подход. Чтобы оптимизировать описанный выше подход, идея состоит в том, чтобы использовать динамическое программирование. Инициализируйте таблицу dp[][] размера N*X , где dp[i][C] хранит количество подмножеств подмассива A[i…N-1] таким образом, что их сумма равна C . Таким образом, повторение очень тривиально, поскольку есть только два варианта выбора, т. е. либо рассматривать i элемент в подмножестве, либо нет. Таким образом, рекуррентное соотношение будет:

dp[i][C] = dp[i – 1][C – A[i]] + dp[i-1][C]

Ниже приведена реализация вышеуказанного подхода:

Временная сложность: O(S*N), где S = сумма элементов массива + K/2 .
Вспомогательное пространство: O(S*N)