子集和问题【回溯算法】

子集和问题就是 给出一个数组arr和一个值sum  输出满足和为sum的arr的子集

子集和问题  从某种程度上来说  其实就是 01背包问题的 子问题   还是取一种情况 不取是另外一种情况  然后  用回溯法  构建出一棵树来遍历一下 

ps:给之前看博客的各位道个歉  print里面arr的下标应该是j 我写了i (已更正)

#include <iostream>
#include <cstring>
 
using namespace std;
 
const int N = 1000; 
 
int arr[N]; // 存储几何元素
bool vis[N]; // 存储集合状态
int valSum;  //当前和
 
void slove(int i , int n , int m){
 
	//超出范围
	if(i > n){
		return ;
	}
 
	// 取数
	vis[i] = true;
	valSum += arr[i];
 
 
	//满足  输出
	if(valSum == m){
		printf("{");
		for(int j = 0; j <= i; j++){
			if(vis[j] == true){
				printf("%d,",arr[j]);
			}
		}
		printf("}\n");
	}else if(valSum < m){     // 不足  继续取数
		slove(i+1,n,m);
	} 
 
 
	//回溯
	vis[i] = false;
	valSum -= arr[i];
 
 	slove(i+1,n,m);
 	return ;
}
 
int main(int argc, char const *argv[])
{
	int num,sum;// num 数组长度  sum 目标和
	scanf("%d%d",&num,&sum);
	for(int i = 0; i < num ;i++){
		scanf("%d",&arr[i]);
	}
 
	slove(0,num,sum);
	return 0;
}

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值