设集合S={x1,x2,…,xn}是一个正整数集合,c是一个正整数,子集和问题判定是否存在S的一个子集S1,使S1中的元素之和为c。试设计一个解子集和问题的回溯法。
输入格式:
输入数据第1行有2个正整数n和c,n表示S的大小,c是子集和的目标值。接下来的1行中,有n个正整数,表示集合S中的元素。 是子集和的目标值。接下来的1 行中,有n个正整数,表示集合S中的元素。
输出格式:
将子集和问题的解输出。当问题无解时,输出“No Solution!”。
输入样例:
在这里给出一组输入。例如:
5 10
2 2 6 5 4
输出样例:
在这里给出相应的输出。例如:
2 2 6
#include
using namespace std;
#define N 10000
int n, c, rest = 0;
int a[N];
int x[N] = {0};
int sum = 0;
bool backtrack(int t)
//子集的前t-1个元素已确定,待确定第t个元素
{
if( ??? )
return true;
//已求到满足条件的解,返回true
if(t>n) //到达叶子结点
return false;
//本路径不存在解,返回false
rest -= a[t];
if(sum+a[t]<=c)
//搜索左分支,即选择第t个数
{
x[t] = ??? ;//选择第t个数
sum = sum + ??? ;
if (backtrack(t+1)) return true;
//backtrack(t+1)==true表示此分支往下搜索能找到解
//故返回true
sum = sum - ???;
}
if(sum+rest>=c)
//若sum+rest<c,则意味着即使把剩下的第t+1~第n个都选了,还是达不到c
//搜索右分支,即不选择第t个数
{
x[t] = ??? ;
if (backtrack(t+1)) return true;
}
rest += ???;
return 0;
}
int main()
{
cin >> n >> c;
for(int i=1; i<= n; i++)
{
cin >> a[i];
rest += a[i];
}
if(!backtrack(1)) cout << "No Solution!";
else
for(int i=1; i<=n; i++)
if (x[i]==1) cout << a[i] << " ";
cout << endl;
return 0;
}
填写a[t]
http://blog.sina.com.cn/s/blog_a31deada0101kp6m.html
贴错了,https://blog.csdn.net/ro_kin/article/details/54139675 一样的程序