/* Function : 求子集和数问题 * Author : wyh7280 * Time : 2015.05.20 10:16:00.000 * Note : 注意输入的集合arr(即函数中的w[i],应确保是单调递增的,如果不是,请在该程序基础上建立结构体,存储每个集合元素 * 原先的编号,并根据集合元素值的大小进行排序。 */ #include <iostream> #include <cstdlib> #include <cstdio> #include <cmath> #include <cstring> using std::cin; using std::cout; using std::endl; //求解函数 void sumOfSub(float s, int k, float r, int *x, float m, float *w); void sumOfSub(int *x, int n, float m, float *w); int main() { int n; //n表示集合元素个数 float m; //m表示目标和 cout << "请输入集合元素个数:"; cin >> n; cout << "请输入目标和:"; cin >> m; float *arr = new float [n + 1]; int *x = new int [n + 1]; //求解状态 cout << "请输入" << n <<"个集合元素(正值):"; for(int i=0; i < n; i++) { cin >> arr[i]; } cout << "可行解: "; sumOfSub(x, n, m, arr); return 0; } void sumOfSub(float s, int k, float r, int *x, float m, float *w) { x[k] = 1; if(s + w[k] == m) //一个可行解 { for(int j = 0;j <= k; j++) //两种输出方式任选 { //cout << x[j] << " "; //完成输出,输出每个元素是否选取的状态,为1表示选取,为0表示未选 if(x[j] == 1) //完成输出,输出选取的元素 cout << w[j] << " "; } cout << endl; } else if(s + w[k] + w[k+1] <= m) { sumOfSub(s+w[k], k+1, r-w[k], x, m, w); //搜索左子树 } if((s + r - w[k] >= m)&&(s + w[k]+1 <= m)) { x[k] = 0; sumOfSub(s, k+1, r - w[k], x, m, w); //搜索右子树 } } void sumOfSub(int *x, int n, float m, float *w) { float r = 0; for(int i = 0; i < n; i++) r += w[i]; //计算总值,判断是否有解 if(r >= m && w[0] <= m) sumOfSub(0, 0, r, x, m, w); }
回溯法的常用例子
版权声明:本文为博主原创文章,未经博主允许不得转载。