问题描述:给定一组整数,从里面选出一组整数,让选择的整数的和与剩下的整数的和的差最小
解题思路:使用子集树,左子树代表选择该节点,右子树代表未选择该节点,当递归遍历到叶子节点的时候,将选择的节点和与未选择的节点和进行做差,选择最小值即可。(子集树的具体概念以及图解参考递归回溯算法_xiaoming1999的博客-CSDN博客)?
题解代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int arr[] = { 12, 6, 7, 11, 16, 3, 9 };
const int length = sizeof(arr) / sizeof(arr[0]);
int sum = 0;//选择的数字的和
int r = 0; //未被选择的数字的和
vector<int> x;//判断当前位置是左孩子还是右孩子,是否被选择
vector<int> bestx;//记录最优的一组子集树
unsigned int min = 0XFFFFFFFF; //记录最小差值
void func(int i)
{
if (i == length)//到叶子节点
{
int result = abs(sum - r);
if (result < min)
{
min = result;
bestx = x;
}
}
else
{
sum += arr[i];
r -= arr[i];
x.push_back(arr[i]);
func(i + 1);
sum -= arr[i]; //递归回溯此时的数字要被减去
r += arr[i];
x.pop_back();
func(i + 1);
}
}
int main()
{
for (int v : arr)
{
r += v;
}
func(0);
cout << "选择的子集:";
for (int v : bestx)
{
cout << v << " ";
}
cout << endl;
cout << "min:" << min << endl;
system("pause");
return 0;
}
?结果如图:
?
?
|