Problem 1205
Description
给出长度为n的数组,求能否从中选出若干个,使他们的和为K.如果可以,输出:Yes,否则输出No
Input
多组输入
第一行:输入N,K,为数组的长度和需要判断的和(2<=N<=20,1<=K<=109)
第二行:N个值,表示数组中元素的值(1<=a[i]<=106)
Output
输出Yes或No
Sample Input
5 13
2 4 6 8 10
Sample Output
No
思路一:二进制枚举法
#include <bits/stdc++.h>
using namespace std;
int main() {
//子集树问题,也可用深搜来做
int n,k,a[22];
bool tag;
while (cin>>n>>k){
tag= false;
for (int i = 0; i < n; ++i) cin>>a[i];
for (int i = 0; i < (1<<n); ++i) {
int sum=0;
for (int j = 0; j < n; ++j) {
if (i>>j&1) sum+=a[j];
}
if (sum==k) {
cout<<"Yes"<<endl; tag= true; break;}
}
if (tag== false) cout<<"No"<<endl;
}
return 0;
}
思路二:深搜
该方法有个问题,就是当深搜到某个地方找到答案时,不知道要怎么停下来,必须要全部搜索一遍。
#include <bits/stdc++.h>
using namespace std;
int sum,n,k,a[22];
bool tag;//初始值为false
void dfs(int pre)
{
if (sum==k) tag= true;
for (int i = pre; i < n; ++i) {
sum+=a[i];
dfs(i+1);
sum-=a[i];
}
}
int main()
{
while(cin>>n>>k){
for (int i = 0; i < n; ++i) cin>>a[i];
sort(a,a+n);
sum=0; tag=false;
dfs(0);
if (tag) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}
有关深搜的复习请参考深搜讲解