Dada una array A[] de tamaño N y un entero diff , la tarea es contar el número de formas de dividir la array en dos subconjuntos ( es posible un subconjunto no vacío ) de modo que la diferencia entre sus sumas sea igual a diff .
Ejemplos:
Entrada: A[] = {1, 1, 2, 3}, diff = 1
Salida: 3
Explicación: Todas las combinaciones posibles son las siguientes:
- {1, 1, 2} y {3}
- {1, 3} y {1, 2}
- {1, 2} y {1, 3}
Todas las particiones tienen diferencia entre sus sumas igual a 1. Por lo tanto, la cuenta de vías es 3.
Entrada: A[] = {1, 6, 11, 5}, diff=1
Salida: 2
Enfoque ingenuo: el enfoque más simple para resolver el problema se basa en las siguientes observaciones:
Sea la suma de los elementos en los subconjuntos de partición S1 y S2 sum1 y sum2 respectivamente . Sea la suma de la array A[ ] X . Dado, sum1 – sum2 = diff – (1) Además, sum1 + sum2 = X – (2)
De las ecuaciones (1) y (2),
sum1 = (X + diff)/2
Por lo tanto, la tarea se reduce a encontrar el número de subconjuntos con una suma dada .
Por lo tanto, el enfoque más simple para resolver este problema es generar todos los subconjuntos posibles y verificar si el subconjunto tiene la suma requerida.
Complejidad temporal: O(2 N )
Espacio auxiliar: O(N)
Enfoque Eficiente: Para optimizar el enfoque anterior, la idea es utilizar Programación Dinámica . Inicialice una tabla dp[][] de tamaño N*X , donde dp[i][C] almacena el número de subconjuntos del subarreglo A[i…N-1] tal que su suma sea igual a C . Por lo tanto, la recurrencia es muy trivial ya que solo hay dos opciones, es decir, considerar el i- ésimo elemento en el subconjunto o no. Entonces la relación de recurrencia será:
dp[i][C] = dp[i – 1][C – A[i]] + dp[i-1][C]
A continuación se muestra la implementación del enfoque anterior:
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; // Function to count the number of ways to divide // the array into two subsets and such that the // difference between their sums is equal to diff int countSubset(int arr[], int n, int diff) { // Store the sum of the set S1 int sum = 0; for (int i = 0; i < n; i++) sum += arr[i]; sum += diff; sum = sum / 2; // Initializing the matrix int t[n + 1][sum + 1]; // Number of ways to get sum // using 0 elements is 0 for (int j = 0; j <= sum; j++) t[0][j] = 0; // Number of ways to get sum 0 // using i elements is 1 for (int i = 0; i <= n; i++) t[i][0] = 1; // Traverse the 2D array for (int i = 1; i <= n; i++) { for (int j = 1; j <= sum; j++) { // If the value is greater // than the sum store the // value of previous state if (arr[i - 1] > j) t[i][j] = t[i - 1][j]; else { t[i][j] = t[i - 1][j] + t[i - 1][j - arr[i - 1]]; } } } // Return the result return t[n][sum]; } // Driver Code int main() { // Given Input int diff = 1, n = 4; int arr[] = { 1, 1, 2, 3 }; // Function Call cout << countSubset(arr, n, diff); }
Java
// Java program for the above approach import java.io.*; public class GFG { // Function to count the number of ways to divide // the array into two subsets and such that the // difference between their sums is equal to diff static int countSubset(int []arr, int n, int diff) { // Store the sum of the set S1 int sum = 0; for (int i = 0; i < n; i++) sum += arr[i]; sum += diff; sum = sum / 2; // Initializing the matrix int t[][] = new int[n + 1][sum + 1]; // Number of ways to get sum // using 0 elements is 0 for (int j = 0; j <= sum; j++) t[0][j] = 0; // Number of ways to get sum 0 // using i elements is 1 for (int i = 0; i <= n; i++) t[i][0] = 1; // Traverse the 2D array for (int i = 1; i <= n; i++) { for (int j = 1; j <= sum; j++) { // If the value is greater // than the sum store the // value of previous state if (arr[i - 1] > j) t[i][j] = t[i - 1][j]; else { t[i][j] = t[i - 1][j] + t[i - 1][j - arr[i - 1]]; } } } // Return the result return t[n][sum]; } // Driver Code public static void main(String[] args) { // Given Input int diff = 1, n = 4; int arr[] = { 1, 1, 2, 3 }; // Function Call System.out.print(countSubset(arr, n, diff)); } } // This code is contributed by AnkThon
Python3
# Python3 program for the above approach # Function to count the number of ways to divide # the array into two subsets and such that the # difference between their sums is equal to diff def countSubset(arr, n, diff): # Store the sum of the set S1 sum = 0 for i in range(n): sum += arr[i] sum += diff sum = sum // 2 # Initializing the matrix t = [[0 for i in range(sum + 1)] for i in range(n + 1)] # Number of ways to get sum # using 0 elements is 0 for j in range(sum + 1): t[0][j] = 0 # Number of ways to get sum 0 # using i elements is 1 for i in range(n + 1): t[i][0] = 1 # Traverse the 2D array for i in range(1, n + 1): for j in range(1, sum + 1): # If the value is greater # than the sum store the # value of previous state if (arr[i - 1] > j): t[i][j] = t[i - 1][j] else: t[i][j] = t[i - 1][j] + t[i - 1][j - arr[i - 1]] # Return the result return t[n][sum] # Driver Code if __name__ == '__main__': # Given Input diff, n = 1, 4 arr = [ 1, 1, 2, 3 ] # Function Call print (countSubset(arr, n, diff)) # This code is contributed by mohit kumar 29
C#
// C# program for the above approach using System; public class GFG { // Function to count the number of ways to divide // the array into two subsets and such that the // difference between their sums is equal to diff static int countSubset(int []arr, int n, int diff) { // Store the sum of the set S1 int sum = 0; for (int i = 0; i < n; i++) sum += arr[i]; sum += diff; sum = sum / 2; // Initializing the matrix int [,]t = new int[n + 1, sum + 1]; // Number of ways to get sum // using 0 elements is 0 for (int j = 0; j <= sum; j++) t[0,j] = 0; // Number of ways to get sum 0 // using i elements is 1 for (int i = 0; i <= n; i++) t[i,0] = 1; // Traverse the 2D array for (int i = 1; i <= n; i++) { for (int j = 1; j <= sum; j++) { // If the value is greater // than the sum store the // value of previous state if (arr[i - 1] > j) t[i,j] = t[i - 1,j]; else { t[i,j] = t[i - 1,j] + t[i - 1,j - arr[i - 1]]; } } } // Return the result return t[n,sum]; } // Driver Code public static void Main(string[] args) { // Given Input int diff = 1, n = 4; int []arr = { 1, 1, 2, 3 }; // Function Call Console.Write(countSubset(arr, n, diff)); } } // This code is contributed by AnkThon
Javascript
<script> // JavaScript program for the above approach // Function to count the number of ways to divide // the array into two subsets and such that the // difference between their sums is equal to diff function countSubset(arr, n, diff) { // Store the sum of the set S1 var sum = 0; for (var i = 0; i < n; i++){ sum += arr[i]; } sum += diff; sum = sum / 2; // Initializing the matrix //int t[n + 1][sum + 1]; var t = new Array(n + 1); // Loop to create 2D array using 1D array for (var i = 0; i < t.length; i++) { t[i] = new Array(sum + 1); } // Loop to initialize 2D array elements. for (var i = 0; i < t.length; i++) { for (var j = 0; j < t[i].length; j++) { t[i][j] = 0; } } // Number of ways to get sum // using 0 elements is 0 for (var j = 0; j <= sum; j++) t[0][j] = 0; // Number of ways to get sum 0 // using i elements is 1 for (var i = 0; i <= n; i++) t[i][0] = 1; // Traverse the 2D array for (var i = 1; i <= n; i++) { for (var j = 1; j <= sum; j++) { // If the value is greater // than the sum store the // value of previous state if (arr[i - 1] > j) t[i][j] = t[i - 1][j]; else { t[i][j] = t[i - 1][j] + t[i - 1][j - arr[i - 1]]; } } } // Return the result return t[n][sum]; } // Driver Code // Given Input var diff = 1; var n = 4; var arr = [ 1, 1, 2, 3 ]; // Function Call document.write(countSubset(arr, n, diff)); </script>
3
Complejidad de tiempo: O(S*N), donde S = suma de los elementos del arreglo + K/2
Espacio auxiliar: O(S*N)
Publicación traducida automáticamente
Artículo escrito por sonigurleen60 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA