問題描述:子集和問題的一個實例爲<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;
}