问题描述:集合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;
}