思路:从
a
1
a_1
a1开始按顺序决定每个数加或不加,在全部n个数都决定后再判断它们的和是否为k即可;时间复杂度为
O
(
2
n
)
O(2^n)
O(2n)
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=20;
ll a[maxn],n,k;
bool dfs(ll i,ll sum){//已经从前i项得到和sum,然后对i项后进行分支
if(i==n) return sum==k;//前n项都计算过,返回sum==k
if(dfs(i+1,sum)) return true;//不取ai
if(dfs(i+1,sum+a[i])) return true;//取ai
return false;//加ai或不加ai都不能凑成k
}
int main(){
cin>>n;
for(ll i=0;i<n;i++) cin>>a[i];
cin>>k;
if(dfs(0,0)) cout<<"Yes";
else cout<<"No";
return 0;
}
优化:剪枝——在递归中只要
s
u
m
≥
k
sum≥k
sum≥k,此后无需继续搜索
问题:如何输出都取了哪些元素