部分和
题目描述
给定a1,a2,…,an,判断是否可以从中选出若干数,使它们的和恰好为k.
样例:
输入
n = 4
a = {1,2,4,7}
k = 13
输出
YES
Solution 1
- 求出a的全部子集
- 判断是否存在子集之和等于k
public class 部分和 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = { 1, 2, 4, 7 };
int[] helper = new int[arr.length];
int k = 13;
int cur = 0;
dfs(arr, helper, k, cur);
}
// 位向量法构造子集
private static void dfs(int[] arr, int[] helper, int k, int cur) {
if (cur == arr.length) {
int sum = 0;
for (int i = 0; i < helper.length; i++) {
if (helper[i] == 1) {
sum += arr[i];
}
}
if (sum == k) {
System.out.println("YES");
}
return;
}
helper[cur] = 0;
dfs(arr, helper, k, cur + 1);
helper[cur] = 1;
dfs(arr, helper, k, cur + 1);
}
}
Solution 2
用DFS搜索解答树
// arr[cur]为当前要决策的元素,该函数定义为从cur位置出发搜索解答树,寻找和为k的分支
private static void dfs(int[] arr, int k, int cur) {
if (k == 0) {
System.out.println("YES");
System.exit(0);
}
if (k < 0 || cur >= arr.length) {
return;
}
// k - arr[cur] = 0时,cur+1可能会越界
dfs(arr, k, cur + 1);// 不选择cur
dfs(arr, k - arr[cur], cur + 1);// 选择cur
}