回溯法—子集和问题(两种)【只需输出一种子集&& 所有情况都输出】
作者:互联网
一.只需输出一种子集
#include <iostream>
using namespace std;
int s[100];//集合
int s1[100];//解集(0/1)
int s2[100];
int n;//数目
int c;//目标加和
int cw;//当前加和
int r;
int best;
bool flag;
void BackTrack(int i)
{
if (i > n) {
if (cw == c) {
for (int i = 1; i <= n; i++)
s2[i]=s1[i];
flag = false;
}
best = cw;
return;
}
if (cw + s[i] <= c) {
s1[i] = 1;
cw += s[i];
BackTrack(i + 1);
cw -= s[i];
}
r -= s[i];
if (cw + r > best) {
s1[i] = 0;
BackTrack(i + 1);
}
r += s[i];
}
int main()
{
cin >> n;
r = 0;
for (int i = 1; i <= n; i++) {
cin >> s[i];
r += s[i];
}
cin >> c;
cw = 0;
best = 0;
flag = true;
BackTrack(1);
if (flag == true) cout << "No solution" << endl;
else {
for (int i = 1; i <= n; i++)
if (s2[i] == 1) cout << s[i] << " ";
cout << endl;
}
}
二.所有情况都输出
#include <iostream>
using namespace std;
int s[100];//集合
int s1[100];//解集(0/1)
int n;//数目
int c;//目标加和
int cw;//当前加和
int r;
int best;
bool flag;
void BackTrack(int i)
{
if (i > n) {
if (cw == c) {
for (int i = 1; i <= n; i++)
if (s1[i] == 1) cout << s[i] << " ";
cout << endl;
flag = false;
}
best = cw;
return;
}
if (cw + s[i] <= c) {
s1[i] = 1;
cw += s[i];
BackTrack(i + 1);
cw -= s[i];
}
r -= s[i];
if (cw + r > best) {
s1[i] = 0;
BackTrack(i + 1);
}
r += s[i];
}
int main()
{
cin >> n;
r = 0;
for (int i = 1; i <=n; i++) {
cin >> s[i];
r += s[i];
}
cin >> c;
cw = 0;
best = 0;
flag = true;
BackTrack(1);
if (flag == true) cout << "No solution" << endl;
}
标签:输出,BackTrack,int,s1,flag,子集,&&,cw,best 来源: https://blog.csdn.net/CeciliaXinn/article/details/121219133