#include <bits/stdc++.h>
using
namespace
std;
struct
Info {
int
sum;
vector<
int
> indices;
};
static
bool
cmp(Info& p1, Info& p2)
{
return
p1.sum < p2.sum;
}
void
generate(vector<
int
>& arr,
int
curr,
int
n,
int
sum,
vector<vector<Info> >& store,
vector<
int
> build)
{
if
(curr == n) {
int
sz = build.size();
store[sz].push_back({ sum, build });
return
;
}
build.push_back(curr);
generate(arr, curr + 1, n, sum + arr[curr], store,
build);
build.pop_back();
generate(arr, curr + 1, n, sum, store, build);
}
int
BINRY_SRCH(vector<Info>& arr,
int
target)
{
int
res = -1;
int
low = 0;
int
high = arr.size() - 1;
while
(low <= high) {
int
mid = (low + high) / 2;
if
(arr[mid].sum >= target) {
res = mid;
high = mid - 1;
}
else
{
low = mid + 1;
}
}
return
res;
}
vector<vector<
int
> > minDifference(vector<
int
>& arr,
int
n)
{
int
extra = (n % 2 != 0);
vector<vector<Info> > part1(n / 2 + 1 + extra);
vector<vector<Info> > part2(n / 2 + 1);
generate(arr, 0, n / 2 + extra, 0, part1, {});
generate(arr, n / 2 + extra, n, 0, part2, {});
for
(
auto
& vec : part2) {
sort(vec.begin(), vec.end(), cmp);
}
vector<vector<
int
> > res(2);
int
diff = INT_MAX;
int
TS = accumulate(arr.begin(), arr.end(), 0);
for
(
int
ele = 1; ele <= n / 2 + extra; ele++) {
vector<Info> P1 = part1[ele];
vector<Info> P2 = part2[n / 2 + extra - ele];
for
(
auto
x : P1) {
int
index = BINRY_SRCH(P2, TS / 2 - x.sum);
if
(index != -1) {
int
subset1_Sum = x.sum + P2[index].sum;
int
subset2_Sum = TS - subset1_Sum;
if
(
abs
(subset1_Sum - subset2_Sum) < diff) {
diff =
abs
(subset1_Sum - subset2_Sum);
vector<
int
> subset1 = x.indices;
for
(
auto
c : P2[index].indices) {
subset1.push_back(c);
}
res[0] = subset1;
}
}
if
(index > 0) {
index--;
int
subset1_Sum = x.sum + P2[index].sum;
int
subset2_Sum = TS - subset1_Sum;
if
(
abs
(subset1_Sum - subset2_Sum) < diff) {
diff =
abs
(subset1_Sum - subset2_Sum);
vector<
int
> subset1 = x.indices;
for
(
auto
c : P2[index].indices) {
subset1.push_back(c);
}
res[0] = subset1;
}
}
}
}
vector<
bool
> vis(n,
false
);
for
(
int
i = 0; i < res[0].size(); i++) {
vis[res[0][i]] =
true
;
res[0][i] = arr[res[0][i]];
}
vector<
int
> subset2;
for
(
int
i = 0; i < n; i++) {
if
(vis[i] ==
false
) {
subset2.push_back(arr[i]);
}
}
res[1] = subset2;
cout <<
"Min Difference "
<< diff << endl;
return
res;
}
void
PRINT(vector<vector<
int
> >& subsets)
{
cout <<
"Subset 1 : "
;
for
(
auto
x : subsets[0]) {
cout << x <<
" "
;
}
cout << endl
<<
"Subset 2 : "
;
for
(
auto
x : subsets[1]) {
cout << x <<
" "
;
}
}
int
main()
{
vector<
int
> arr;
vector<vector<
int
> > res;
arr = {45, 34, 4, 12, 5, 2 };
res = minDifference(arr, arr.size());
PRINT(res);
return
0;
}