-
题目
- 给定整数 a1、a2、...、an a 1 、 a 2 、 . . . 、 a n ,判断是否可以从中选出若干数,使它们的和恰好为 k k 。
- 样例1
- 输入
n=4
a={1,2,4,7}
k=13
- 输出
Yes {13 = 2 + 4 + 7}
- 样例2
- 输入
n = 4
a = {1,2,4,7}
k = 15
- 输出
No
这里我们采用深度优先算法(DFS,Depth-First Search),它从某个状态开始,不断地转移状态直到无法转移,然后回退到前一步的状态,继续转移到其他状态。如此不断重复,直至找到最终的解。
我们从开始按顺序决定每个数加或不加,在全部n个数都决定后再判断它们的和是不是 k k 即可。所以复杂度是。注意 a a <script type="math/tex" id="MathJax-Element-368">a</script>的下标与题目中描述的下标偏移了1.在程序中使用的是0起始的下标规则。题目描述中则是1开始的,这点要注意避免混淆。
// 输入
int a[MAX_N];
int n, k;
// 已经从前i项得到了和sum,然后对于i项之后的进行分支
bool dfs(int i, int sum){
// 如果前n项都计算过了,则返回sum是否与k相等
if(i == n) return sum == k;
// 不加上a[i]的情况
if(dfs(i+1,sum)) return true;
// 加上a[i]的情况
if(dfs(i + 1, sum + a[i+1])) return true;
//无论是否加上a[i]都不能凑成k就返回false
return true;
}
void solve(){
if( dfs(0, 0) ) printf("YES\n");
else printf("No\n");
}