Find maximum subset sum formed by partitioning any subset of array into 2 partitions with equal sum - GeeksforGeeks

09 Aug, 2021
Given an array A containing N elements. Partition any subset of this array into two disjoint subsets such that both the subsets have an identical sum. Obtain the maximum sum that can be obtained after partitioning. 
Note: It is not necessary to partition the entire array, that is any element might not contribute to any of the partition.
Examples: 
Input: A = [1, 2, 3, 6] Output: 6 Explanation: We have two disjoint subsets {1, 2, 3} and {6}, which have the same sum = 6
Input: A = [1, 2, 3, 4, 5, 6] Output: 10 Explanation: We have two disjoint subsets {2, 3, 5} and {4, 6}, which have the same sum = 10.
Input: A = [1, 2] Output: 0 Explanation: No subset can be partitioned into 2 disjoint subsets with identical sum  
Naive Approach: The above problem can be solved by brute force method using recursion. All the elements have three possibilities. Either it will contribute to partition 1 or partition 2 or will not be included in any of the partitions. We will perform these three operations on each of the elements and proceed to the next element in each recursive step.
Below is the implementation of the above approach:  
C++
Java
Python3
C#
Javascript
// CPP implementation for the// above mentioned recursive approach #include <bits/stdc++.h> using namespace std; // Function to find the maximum subset sumint maxSum(int p0, int p1, int a[], int pos, int n){    if (pos == n) {        if (p0 == p1)            return p0;        else            return 0;    }    // Ignore the current element    int ans = maxSum(p0, p1, a, pos + 1, n);     // including element in partition 1    ans = max(ans, maxSum(p0 + a[pos], p1, a, pos + 1, n));     // including element in partition 2    ans = max(ans, maxSum(p0, p1 + a[pos], a, pos + 1, n));    return ans;} // Driver codeint main(){    // size of the array    int n = 4;    int a[n] = { 1, 2, 3, 6 };    cout << maxSum(0, 0, a, 0, n);    return 0;}
// Java implementation for the// above mentioned recursive approachclass GFG {         // Function to find the maximum subset sum    static int maxSum(int p0, int p1, int a[], int pos, int n)    {        if (pos == n) {            if (p0 == p1)                return p0;            else                return 0;        }         // Ignore the current element        int ans = maxSum(p0, p1, a, pos + 1, n);             // including element in partition 1        ans = Math.max(ans, maxSum(p0 + a[pos], p1, a, pos + 1, n));             // including element in partition 2        ans = Math.max(ans, maxSum(p0, p1 + a[pos], a, pos + 1, n));        return ans;    }         // Driver code    public static void main (String[] args)    {        // size of the array        int n = 4;        int a[] = { 1, 2, 3, 6 };        System.out.println(maxSum(0, 0, a, 0, n));             }} // This code is contributed by AnkitRai01
# Python3 implementation for the# above mentioned recursive approach # Function to find the maximum subset sumdef maxSum(p0, p1, a, pos, n) :     if (pos == n) :        if (p0 == p1) :            return p0;        else :            return 0;         # Ignore the current element    ans = maxSum(p0, p1, a, pos + 1, n);     # including element in partition 1    ans = max(ans, maxSum(p0 + a[pos], p1, a, pos + 1, n));     # including element in partition 2    ans = max(ans, maxSum(p0, p1 + a[pos], a, pos + 1, n));         return ans; # Driver codeif __name__ == "__main__" :     # size of the array    n = 4;    a = [ 1, 2, 3, 6 ];         print(maxSum(0, 0, a, 0, n)); # This code is contributed by AnkitRai01
// C# implementation for the// above mentioned recursive approach using System; public class GFG {         // Function to find the maximum subset sum    static int maxSum(int p0, int p1, int []a, int pos, int n)    {        if (pos == n) {            if (p0 == p1)                return p0;            else                return 0;        }         // Ignore the current element        int ans = maxSum(p0, p1, a, pos + 1, n);             // including element in partition 1        ans = Math.Max(ans, maxSum(p0 + a[pos], p1, a, pos + 1, n));             // including element in partition 2        ans = Math.Max(ans, maxSum(p0, p1 + a[pos], a, pos + 1, n));        return ans;    }         // Driver code    public static void Main (string[] args)    {        // size of the array        int n = 4;        int []a = { 1, 2, 3, 6 };        Console.WriteLine(maxSum(0, 0, a, 0, n));             }} // This code is contributed by AnkitRai01
<script> // Javascript implementation for the// above mentioned recursive approach // Function to find the maximum subset sumfunction maxSum(p0, p1, a, pos, n){    if (pos == n)    {        if (p0 == p1)            return p0;        else            return 0;    }         // Ignore the current element    var ans = maxSum(p0, p1, a, pos + 1, n);     // Including element in partition 1    ans = Math.max(ans, maxSum(        p0 + a[pos], p1, a, pos + 1, n));     // Including element in partition 2    ans = Math.max(ans, maxSum(        p0, p1 + a[pos], a, pos + 1, n));    return ans;} // Driver code // Size of the arrayvar n = 4;var a = [ 1, 2, 3, 6 ]; document.write(maxSum(0, 0, a, 0, n)); // This code is contributed by importantly </script>
6
 
Time Complexity: Auxiliary Space: O(n) 
Efficient Approach: The above method can be optimized using Dynamic Programming method. We will define our DP state as follows : 
dp[i][j] = Max sum of group g0 considering the first i elements such that,the difference between the sum of g0 and g1 is (sum of all elements – j), where j is the difference.So, the answer would be dp[n][sum]
Now we might encounter, the difference between the sums is negative, lying in the range [-sum, +sum], where the sum is a summation of all elements. The minimum and maximum ranges occurring when one of the subsets is empty and the other one has all the elements. Due to this, in the DP state, we have defined j as (sum – diff). Thus, j will range from [0, 2*sum].
Below is the implementation of the above approach: 
C++
Java
Python3
C#
Javascript
// CPP implementation for the above mentioned// Dynamic Programming  approach #include <bits/stdc++.h> using namespace std; // Function to find the maximum subset sumint maxSum(int a[], int n){    // sum of all elements    int sum = 0;    for (int i = 0; i < n; i++)        sum += a[i];     int limit = 2 * sum + 1;     // bottom up lookup table;    int dp[n + 1][limit];     // initialising dp table with INT_MIN    // where, INT_MIN means no solution    for (int i = 0; i < n + 1; i++) {        for (int j = 0; j < limit; j++)            dp[i][j] = INT_MIN;    }     // Case when diff is 0    dp[0][sum] = 0;    for (int i = 1; i <= n; i++) {        for (int j = 0; j < limit; j++) {             // Putting ith element in g0            if ((j - a[i - 1]) >= 0 && dp[i - 1][j - a[i - 1]] != INT_MIN)                 dp[i][j] = max(dp[i][j], dp[i - 1][j - a[i - 1]]                                             + a[i - 1]);             // Putting ith element in g1            if ((j + a[i - 1]) < limit && dp[i - 1][j + a[i - 1]] != INT_MIN)                 dp[i][j] = max(dp[i][j], dp[i - 1][j + a[i - 1]]);             // Ignoring ith element            if (dp[i - 1][j] != INT_MIN)                 dp[i][j] = max(dp[i][j], dp[i - 1][j]);        }    }     return dp[n][sum];} // Driver code int main(){    int n = 4;    int a[n] = { 1, 2, 3, 6 };    cout << maxSum(a, n);    return 0;}
// Java implementation for the above mentioned// Dynamic Programming approachclass GFG {         final static int INT_MIN = Integer.MIN_VALUE;         // Function to find the maximum subset sum    static int maxSum(int a[], int n)    {        // sum of all elements        int sum = 0;        for (int i = 0; i < n; i++)            sum += a[i];             int limit = 2 * sum + 1;             // bottom up lookup table;        int dp[][] = new int[n + 1][limit];             // initialising dp table with INT_MIN        // where, INT_MIN means no solution        for (int i = 0; i < n + 1; i++) {            for (int j = 0; j < limit; j++)                dp[i][j] = INT_MIN;        }             // Case when diff is 0        dp[0][sum] = 0;        for (int i = 1; i <= n; i++) {            for (int j = 0; j < limit; j++) {                     // Putting ith element in g0                if ((j - a[i - 1]) >= 0 && dp[i - 1][j - a[i - 1]] != INT_MIN)                         dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - a[i - 1]]                                                + a[i - 1]);                     // Putting ith element in g1                if ((j + a[i - 1]) < limit && dp[i - 1][j + a[i - 1]] != INT_MIN)                         dp[i][j] = Math.max(dp[i][j], dp[i - 1][j + a[i - 1]]);                     // Ignoring ith element                if (dp[i - 1][j] != INT_MIN)                         dp[i][j] = Math.max(dp[i][j], dp[i - 1][j]);            }        }             return dp[n][sum];    }         // Driver code    public static void main (String[] args)    {        int n = 4;        int []a = { 1, 2, 3, 6 };        System.out.println(maxSum(a, n));    }} // This code is contributed by AnkitRai01
# Python3 implementation for the above mentioned# Dynamic Programming approachimport numpy as npimport sys INT_MIN = -(sys.maxsize - 1) # Function to find the maximum subset sumdef maxSum(a, n) :     # sum of all elements    sum = 0;    for i in range(n) :        sum += a[i];     limit = 2 * sum + 1;     # bottom up lookup table;    dp = np.zeros((n + 1,limit));     # initialising dp table with INT_MIN    # where, INT_MIN means no solution    for i in range(n + 1) :        for j in range(limit) :            dp[i][j] = INT_MIN;     # Case when diff is 0    dp[0][sum] = 0;    for i in range(1, n + 1) :        for j in range(limit) :             # Putting ith element in g0            if ((j - a[i - 1]) >= 0 and dp[i - 1][j - a[i - 1]] != INT_MIN) :                 dp[i][j] = max(dp[i][j], dp[i - 1][j - a[i - 1]]                                            + a[i - 1]);             # Putting ith element in g1            if ((j + a[i - 1]) < limit and dp[i - 1][j + a[i - 1]] != INT_MIN) :                 dp[i][j] = max(dp[i][j], dp[i - 1][j + a[i - 1]]);             # Ignoring ith element            if (dp[i - 1][j] != INT_MIN) :                 dp[i][j] = max(dp[i][j], dp[i - 1][j]);                     return dp[n][sum]; # Driver code if __name__ == "__main__" :     n = 4;    a = [ 1, 2, 3, 6 ];    print(maxSum(a, n)); # This code is contributed by Yash_R
// C# implementation for the above mentioned// Dynamic Programming approachusing System; class GFG {         static int INT_MIN = int.MinValue;         // Function to find the maximum subset sum    static int maxSum(int []a, int n)    {        // sum of all elements        int sum = 0;        for (int i = 0; i < n; i++)            sum += a[i];             int limit = 2 * sum + 1;             // bottom up lookup table;        int [,]dp = new int[n + 1,limit];             // initialising dp table with INT_MIN        // where, INT_MIN means no solution        for (int i = 0; i < n + 1; i++) {            for (int j = 0; j < limit; j++)                dp[i,j] = INT_MIN;        }             // Case when diff is 0        dp[0,sum] = 0;        for (int i = 1; i <= n; i++) {            for (int j = 0; j < limit; j++) {                     // Putting ith element in g0                if ((j - a[i - 1]) >= 0 && dp[i - 1,j - a[i - 1]] != INT_MIN)                         dp[i,j] = Math.Max(dp[i,j], dp[i - 1,j - a[i - 1]]                                                + a[i - 1]);                     // Putting ith element in g1                if ((j + a[i - 1]) < limit && dp[i - 1,j + a[i - 1]] != INT_MIN)                         dp[i,j] = Math.Max(dp[i,j], dp[i - 1,j + a[i - 1]]);                     // Ignoring ith element                if (dp[i - 1,j] != INT_MIN)                         dp[i,j] = Math.Max(dp[i,j], dp[i - 1,j]);            }        }             return dp[n,sum];    }         // Driver code    public static void Main()    {        int n = 4;        int []a = { 1, 2, 3, 6 };        Console.WriteLine(maxSum(a, n));    }} // This code is contributed by Yash_R
<script>  // JavaScript implementation for the above mentioned// Dynamic Programming  approach // Function to find the maximum subset sumfunction maxSum(a, n){    // sum of all elements    var sum = 0;    for (var i = 0; i < n; i++)        sum += a[i];     var limit = 2 * sum + 1;     // bottom up lookup table;    var dp = Array.from(Array(n+1), ()=>Array(limit));     // initialising dp table with -1000000000    // where, -1000000000 means no solution    for (var i = 0; i < n + 1; i++) {        for (var j = 0; j < limit; j++)            dp[i][j] = -1000000000;    }     // Case when diff is 0    dp[0][sum] = 0;    for (var i = 1; i <= n; i++) {        for (var j = 0; j < limit; j++) {             // Putting ith element in g0            if ((j - a[i - 1]) >= 0 &&            dp[i - 1][j - a[i - 1]] != -1000000000)                 dp[i][j] = Math.max(dp[i][j],                dp[i - 1][j - a[i - 1]] + a[i - 1]);             // Putting ith element in g1            if ((j + a[i - 1]) < limit &&            dp[i - 1][j + a[i - 1]] != -1000000000)                 dp[i][j] = Math.max(dp[i][j],                dp[i - 1][j + a[i - 1]]);             // Ignoring ith element            if (dp[i - 1][j] != -1000000000)                 dp[i][j] = Math.max(dp[i][j], dp[i - 1][j]);        }    }     return dp[n][sum];} // Driver codevar n = 4;var a = [1, 2, 3, 6];document.write( maxSum(a, n)); </script>
6
 
Time Complexity: , where Sum represents sum of all array elements. Auxiliary Space:  
ankthon
Yash_R
importantly
rrrtnx
pankajsharmagfg
subset
Algorithms
Competitive Programming
Dynamic Programming
Recursion
Dynamic Programming
Recursion
subset
Algorithms
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
DSA Sheet by Love Babbar
How to Start Learning DSA?
Difference between Algorithm, Pseudocode and Program
K means Clustering - Introduction
Types of Complexity Classes | P, NP, CoNP, NP hard and NP complete
Competitive Programming - A Complete Guide
Practice for cracking any coding interview
Arrow operator -> in C/C++ with Examples
Prefix Sum Array - Implementation and Applications in Competitive Programming
Fast I/O for Competitive Programming