描述
一个数组中有若干正整数,将此数组划分为两个子数组,使得两个子数组的各元素之和 a,b 的差最小。
输入描述:
共一行,包含若干个正整数,表示给定数组。
输出描述:
以降序的顺序,输出两个子数组的各元素之和。
输入
10 20 30 10 10
输出
40 40
代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;
int sum = 0; //记录数组的和
int diff = 0; // 记录遍历过程最小的差值
bool exitFlag = false; // 记录是否要提前退出
void DFSFindMinDiff(vector<int> &arr, int pos, int sa) {
if (pos == arr.size() || exitFlag == true) {
return;
}
// arr[pos] 放入到 a集合当中
int newdiff; //记录当前的差值
if (2 * (sa + arr[pos]) - sum > 0) {
newdiff = 2 * (sa + arr[pos]) - sum;
}
else {
newdiff = sum - 2 * (sa + arr[pos]);
}
if (newdiff < diff) {
diff = newdiff;
if (diff == 0 || diff == 1 || 2 * arr[pos] > sum) {
exitFlag = true;
}
}
if (2 * (sa + arr[pos]) - sum < 0) {
DFSFindMinDiff(arr, pos + 1, sa + arr[pos]);
}
// arr[pos] 不放入 a集合中
DFSFindMinDiff(arr, pos + 1, sa);
}
bool compare(int lhs, int rhs) {
return lhs > rhs;
}
int main() {
vector<int> arr;
int i;
while (scanf("%d", &i) != EOF) {
arr.push_back(i);
}
for (int i = 0; i < arr.size(); ++i) {
sum += arr[i];
}
diff = sum;
sort(arr.begin(), arr.end(), compare);
DFSFindMinDiff(arr, 0, 0);
// sa+sb = sum
// sb-sa = diff
int sa = (sum - diff) / 2;
int sb = sa + diff;
printf("%d %d\n", sb, sa);
return 0;
}