Подсчитайте способы поставить «+» и «-» перед элементами массива, чтобы получить сумму K
Опубликовано: 22 Сентября, 2022
Дан массив A[] , состоящий из N неотрицательных целых чисел, и целое число K , задача состоит в том, чтобы найти количество способов, которыми операторы «+» и «-» могут быть размещены перед элементами массива A[] таким образом, что сумма массива становится K .
Примеры:
Input: A[] = {1, 1, 2, 3}, N = 4, K = 1
Output: 3
Explanation: Three possible ways are:
- + 1 + 1 + 2 – 3 = 1
- + 1 – 1 – 2 + 3 = 1
- – 1 + 1 – 1 + 3 = 1
Input: A[] = {1, 1, 1, 1, 1}, N = 5, K = 3
Output: 5
Подход: Задача может быть решена на основе следующих наблюдений:
- Сохраните сумму элементов, имеющих «+» перед этим элементом и «-» перед этим элементом в переменных, скажем, P1 и P2 , чтобы сумма массива стала K.
- Сохраните общую сумму массива A[] в переменной, скажем, K .
- Следовательно, возникают следующие уравнения:
- P1 + P2 = сумма
- П1 – П2 = К
- Решение приведенных выше уравнений дает P1 = (сумма + K) / 2 .
- Поэтому задача трансформировалась в нахождение количества подмножеств с суммой P1.
- Если элемент A равен 0 , оба оператора '+' и '-' работают в допустимых сочетаниях, таким образом, 0 можно безопасно игнорировать и вычислять отдельно.
Следовательно, проблема может быть решена с помощью динамического программирования. Выполните следующие шаги, чтобы решить проблему:
- Вычислите и сохраните сумму элементов массива A[] и количество нулей в A[] в переменных sum и c соответственно.
- Если K больше суммы или (сумма + K) нечетно, вернуть 0 .
- Добавьте K к сумме и разделите ее на 2, т.е. сумма = (сумма + K) / 2 , что является требуемой суммой. Найдите количество подмножеств, равных этой сумме.
- Создайте массив 2D dp размерностей N*sum . где dp[i][j] представляет количество подмножеств до i-1 , которые имеют сумму j .
- Базовые случаи, которые необходимо учитывать, следующие:
- dp[0][i] = 0 , для 0 <= i <= sum , так как элементы массива A[] не учитывались
- dp[i][0] = 1 , для 0 <= i <= N , так как всегда возможно получение суммы 0 .
- Итерируйте от 1 до N и для каждого текущего индекса i выполните следующие операции:
- Итерируйте от 1 до суммы и для каждого текущего индекса j выполните следующие переходы:
- Если A[i – 1] меньше j и A[i – 1] не равно 0 , установите dp[i][j] = dp[i – 1][j] + dp[i – 1][ j – A[i – 1]].
- В противном случае скопируйте предыдущее состояние, т.е. dp[i][j] = dp[i – 1][j].
- Итерируйте от 1 до суммы и для каждого текущего индекса j выполните следующие переходы:
- Наконец, верните произведение dp[N][sum] и 2 c (для учета нулей), т.е. dp[N][sum]*2 c .
Ниже приведена реализация вышеуказанного подхода:
Временная сложность: O(N * сумма)
Вспомогательное пространство: O(N * сумма)