这是问题所在:
您有 N 个(N 代表您拥有的数字的数量)个数。将它们分成两组,使组中数字之和之间的差异最小。
例子:
5 // N
1, 9, 5, 3, 8 // The numbers
如果我们将 1、9 和 3 放入 A 组,将 5 和 8 放入 B 组,则差异为 0。
我认为首先我应该计算所有数字的总和并将其除以 2。然后检查任何可能的数字组合,其总和不高于所有数字总和的一半。完成此操作后,我将选择最大的数字并打印出组。
我在遍历所有组合时遇到问题,特别是当 N 是大数字时。如何运行所有组合?
另外我的想法有点不同,我会按降序对数字进行分组,然后将最大的数字放在 A 组中,将最小的数字放在 B 组中。然后我反过来做。这适用于某些数字,但有时它不会显示最佳分组。例如:
如果我使用前面的例子。按降序排列数字。
9, 8, 5, 3, 1.
把最大的放在 A 组,把最小的放在 B 组。
Group A: 9
Group B: 1
反过来。
Group A: 9, 3
Group B: 1, 8
等等。如果最后我只有一个数字,我会把它放在总和较低的组中。所以我最终会得到:
Group A: 9, 3
Group B: 1, 8, 5
这不是最佳分组,因为差异为 2,但以不同的方式分组,差异可能为 0,正如我所展示的。
如何获得最佳分组?
代码:
#include <iostream>
#include <cmath>
#include <string>
using namespace std;
int convertToBinary(int number) {
int remainder;
int binNumber = 0;
int i = 1;
while(number!=0)
{
remainder=number%2;
binNumber=binNumber + (i*remainder);
number=number/2;
i=i*10;
}
return binNumber;
}
int main()
{
int number, combinations, sum = 0;
double average;
cin >> number;
int numbers[number];
for(int i = 0; i<number; i++)
{
cin >> numbers[i];
sum += numbers[i];
}
if(sum%2 == 0)
{
average = sum/2;
}
else
{
average = sum/2 + 0.5;
}
combinations = pow(2,number-1);
double closest = average;
for(int i = 0; i<=combinations;i++)
{
int rem;
int temp_sum = 0;
int state = convertToBinary(i);
for(int j = 0; state!=0; j++)
{
int rem =state%10;
state = state/10;
if(rem == 1)
{
temp_sum = temp_sum + numbers[j];
}
}
if(abs(average-temp_sum)<closest)
{
closest = abs(average-temp_sum);
if(closest == 0)
{
break;
}
}
}
cout << closest*2;
return 0;
}