您的位置:首页 > 其它

题目1058 部分和问题 简单dfs

2018-03-22 18:02 411 查看

部分和问题

时间限制:1000 ms  |  内存限制:65535 KB 难度:2描述 给定整数a1、a2、.......an,判断是否可以从中选出若干数,使它们的和恰好为K。输入首先,n和k,n表示数的个数,k表示数的和。
接着一行n个数。
(1<=n<=20,保证不超int范围)输出如果和恰好可以为k,输出“YES”,并按输入顺序依次输出是由哪几个数的和组成,否则“NO”样例输入
4 13
1 2 4 7
样例输出
YES
2 4 7
正确代码
import java.util.Scanner;
import java.util.Arrays;

public class M {

static final int MAX = 22;
static int k, n;
static int[] a = new int[MAX];
static int[] b = new int[MAX];//标记数组,便于输出参与计算的a[i]
//最后要输出所有被加的数,随时标记是否要输出这个数字

// 从左到右遍历一遍可得解 初始化x=0,sun=0 dfs(0,0);到dfs(n,k);
static boolean dfs(int x, int sum) {
if (sum > k)
return false; // 剪枝,当sum超过k时,也没必要继续搜索
if (x == n+1)
return sum == k; // 如果前n项计算过了,返回sum=k是否相等
//如果前n项没计算,x + 1继续向右搜索
if (dfs(x + 1, sum)) {
b[x] = 0;//不加此时的a[x],标记为0;
return true;
}
if (dfs(x + 1, sum + a[x])) {
b[x] = 1;// 如果加上a[x]的情况,标记为1;
return true;
}
else
return false;
}

public static void main(String[] args) {
// TODO Auto-generated method stub

Scanner cin = new Scanner(System.in);

// 输入
n = cin.nextInt();
k = cin.nextInt();
for (int i = 1; i <= n; i++) {
a[i] = cin.nextInt();
}

// 深搜(从最左边开始)
if (dfs(1, 0)) {
System.out.println("YES");
//输出所有参与计算的数字
for (int i = 1; i <=n; i++)
//b[i]作为标记
if (b[i] == 1){
System.out.print(a[i]);
if(i<n)
System.out.print(" ");
}
System.out.println();
}
}
}//
当时遇到的错误:搜索的时候数组索引与输入时的索引不对应
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: