Set Sum Partition

Minimum Sum Partition

Given an array, the task is to divide it into two sets S1 and S2 such that the absolute difference between their sums is minimum.

  • Input:
    The first line contains an integer ‘T’ denoting the total number of test cases. In each test cases, the first line contains an integer ‘N’ denoting the size of array. The second line contains N space-separated integers A1, A2, …, AN denoting the elements of the array.

  • Output:
    In each seperate line print minimum absolute difference.

  • Constraints:
    1<=T<=30
    1<=N<=50
    1<=A[I]<=50

Example:

  • Input:
    2
    4
    1 6 5 11
    4
    36 7 46 40
  • Output :
    1
    23
  • Explaination :
    Subset1 = {1, 5, 6}, sum of Subset1 = 12
    Subset2 = {11}, sum of Subset2 = 11

test

Solution

The DP equation should be:

  • f(i, sum)=abs(f(i-1, sum)-sum) \< abs(f(i-1, sum-ai)+ai-sum)? f(i-1,sum):f(i-1,sum-ai)+ai

Note f(i, sum) means till arr[i] number, the closest sum to the sum in f(i, sum).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <vector>
using namespace std;
int getClosestSum(int pos, const vector<int>& arr, const int& sum, vector<vector<int>>& dp){
if(pos == -1) return 0;
if(dp[pos][sum] != -1) return dp[pos][sum];
int t0 = getClosestSum(pos-1, arr, sum, dp);
int t1 = getClosestSum(pos-1, arr, sum-arr[pos], dp)+arr[pos];
return dp[pos][sum] = abs(t0-sum)<abs(t1-sum)? t0:t1;
}
int main() {
int count = 0;
cin>>count;
while(count--){
int size = 0, sum = 0;
cin>>size;
vector<int> arr(size), parents(size, -1);
for(int i = 0; i < size; ++i) {
cin>>arr[i];
sum += arr[i];
}
int target = sum >> 1;
vector<vector<int>> dp(size, vector<int>(sum+1, -1));
cout<<abs(sum-2*getClosestSum(size-1, arr, target, dp))<<endl;
}
return 0;
}

Always welcome new ideas and practical tricks, just leave them in the comments!