问题描述:子集和问题的一个实例为<S, t>。其中,S={x1, x2, ……,xn}是一个正整数的集合,c是一个正整数。子集和问题判定是否存在S的一个子集S1, 使得S1的子集和等于c。
试设计一个解子集和问题的回溯法。
数据输入:由文件input.txt提供输入数据。文件第1行有2个正整数n和c,n表示S的大小,c是子集和的目标值。接下来的1行中,有n个正整数,表示集合S中的元素。
结果输出:将子集和问题的解输出到文件output.txt。当问题无解时,输出"No Soletion!"。
输入文件示例:
input.txt
5 10
2 2 6 5 4
输出文件示例
output.txt
2 2 6
class Subset_sum_problem{
private:
int arr[100];
int index[100];
int arr_length;
int current;
int remain;
int des_c;
int number;
void count_sum();
void Print();
void Backtrack(int i);
public:
Subset_sum_problem(int* a, int length, int c);
void solve();
};
Subset_sum_problem.cpp
#include"Subset_sum_problem.h"
#include<iostream>
Subset_sum_problem::Subset_sum_problem(int* a, int length, int c){
for (int i = 0; i < length; i++){
arr[i] = a[i];
index[i] = 0;
}
arr_length = length;
des_c = c;
current = 0;
number = 0;
count_sum();
}
void Subset_sum_problem::count_sum(){
int temp_sum = 0;
for (int i = 0; i < arr_length; i++){
temp_sum += arr[i];
}
remain = temp_sum;
}
void Subset_sum_problem::solve(){
Backtrack(0);
if (number == 0){
std::cout << "No Solution!" << std::endl;
}
}
void Subset_sum_problem::Print(){
for (int i = 0, temp_sum = 0; temp_sum != des_c; i++){
if (index[i] == 1){
std::cout << arr[i] << " ";
temp_sum += arr[i];
}
}
std::cout << std::endl;
}
void Subset_sum_problem::Backtrack(int i){
if (i == arr_length){
return;
}else{
if (current + arr[i] == des_c){
index[i] = 1;
number++;
Print();
return;
}else{
remain -= arr[i];
if ((current + arr[i]) < des_c && (current + arr[i] + remain) >= des_c){
index[i] = 1;
current += arr[i];
Backtrack(i + 1);
index[i] = 0;
current -= arr[i];
}
if (current + remain >= des_c){
index[i] = 0;
Backtrack(i + 1);
}
remain += arr[i];
}
}
}
main.cpp
#include"Subset_sum_problem.h"
#include<iostream>
int main(void){
int n = 5, c = 10;
std::cin >> n >> c;
int* a = new int[n];
for (int i = 0; i < n; i++){
std::cin >> a[i];
}
Subset_sum_problem demo(a, n, c);
demo.solve();
return 0;
}