递归-子集和问题

问题描述:集合M(M元素个数≤100),整数S(≤20000),问集合M里面是否存在子集和等于S。若相等,返回Ture,否则,返回False.
输入样例1:
4 7
6 4 2 1
输出样例1:
True

输入样例2:
4 20
6 3 4 2
输出样例:
False

坑点1:此程序执行需要剪枝,时间复杂度为O(NS)否则为2^N
坑点2:当集合M内为98个1 第99个为100 S为100时,则剪枝无效

样例1执行图示:

在这里插入图片描述
Code:

#include<iostream>
#include<algorithm>
using namespace std;
int *a,N,S;
bool subset(int i,int sum){//存储下标和总值和 
	//剪枝 
	if(sum==S)//当sum==S时说明子序列里面存在元素相加为S 
		return true;
	if(i>=N)//当i大于元素个数N的时候说明未找到 即使写i>=N也不会崩掉
	//因为如果i与N的个数相等时候sum==S那么他就会在上面执行返回走了 
		return false;
	if(sum>S)//当执行到此处前面的子元素加起来已经超过S了 后面没有必要再继续执行了 
		return false;
	subset(i+1,sum+a[i])||subset(i+1,sum);//选则某个值(在sum里面累加上a[i])和不选 
}
int main(){
	cin>>N>>S;
	a=new int[N];
	for(int i=0;i<N;i++)
		cin>>a[i];
	string res=subset(0,0)?"True":"False";
	cout<<res;
	return 0;
} 
发布了5 篇原创文章 · 获赞 5 · 访问量 82

猜你喜欢

转载自blog.csdn.net/Fight_adu/article/details/104742779