部分和问题
时间限制:
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(); } } }//
当时遇到的错误:搜索的时候数组索引与输入时的索引不对应