回溯法之子集和问题
来源:互联网 发布:c 对端口的访问被拒绝 编辑:程序博客网 时间:2024/06/11 12:44
问题描述:设集合S={x1,x2,…,xn}是一个正整数集合,c是一个正整数,子集和问题判定是否存在S的一个子集S1,使S1中的元素之和为c。试设计一个解子集和问题的回溯法。将子集和问题的解输出。当问题无解时,输出“No Solution!”。
因为我在代码里的注释已经写了很多了,大家将就看着注释理解哈
直接贴代码:
#include<iostream>using namespace std;#define N 10000int n, c, rest = 0;//rest表示从当前元素加到最后一个元素的总和,用来回溯时判断限界剪枝 int a[N];//a[N]存储S集合元素 ,最多可以存储N个 int x[N] = {0};//设置x[N]来表示a[N]元素是否选择,初始为0,若为1则表示选择 int sum = 0;//当前所选元素之和bool backtrack(int t)//调用这个方法判断是否有解 { if( sum == c ) return true; // 找到可行解 if( t > n ) return false ;//找不到可行解 rest-=a[t]; if(sum + a[t] <= c)//可以取a[t],在子集树中表示走左分支 { x[t] = 1 ;//选择a[t] ,赋值为1 sum = sum+a[t] ; if ( backtrack(t+1) ) return true; sum -= a[t];//回溯时要把之前加的减掉 } if( sum + rest >= c) //没办法确实不行,利用rest判断限界剪枝 ,在子集树中表示走右分支 { x[t] = 0 ; if ( backtrack(t+1) ) return true; } rest += a[t];//把之前减掉的加回来 return false;//当层遍历后发现没有解决方案,返回false回去上一层}int main(){ cin >>n>>c;//初始化集合元素个数n和目标值c for (int i = 1; i <= n; i++) { cin >> a[i];//依次输入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;}
谢谢阅读,欢迎讨论建议或指正
0 0
- 回溯法之子集和问题
- 回溯法之子集和问题
- 回溯法 子集和问题
- 回溯法2--子集和问题
- 子集和问题 回溯法求解
- 回溯法解决子集和问题
- 回溯法解决子集和问题
- 回溯法---子集和
- 回溯法例题之子集树:数组定和问题
- 回溯法-子集和数问题
- 回溯法---->子集和数问题
- 【回溯法】求子集问题
- 回溯之子集树法
- 回溯法之子集树
- 用回溯法解决子集和问题【C#版本】
- 回溯法实现求解子集合和问题
- 回溯算法-定和子集问题
- 回溯之子集树和排列树
- eval()
- MBNetwork-Network request can be easier
- [Leetcode] Triangle
- C++:读取数量不定的输入数据
- Face Detection Data Set and Benchmark文章系列1 FDDB technical report review
- 回溯法之子集和问题
- MYSQL基础知识
- Codeforces_509E:Pretty_Song(想法题)
- js实现简单的动态添加或删除一行数据
- 微信小程序案例:获取微信访问用户的openid
- 原来 CSS 这样写是会让 App 崩溃的(转载自一个携程员工博客)
- js拼音排序并按字母分类
- 卡尔曼滤波
- JQuery上