DESearchAlgorithm

177 阅读1分钟

题目

给定整数a1,a2,a3…an,判断能否从中选出若干数,使他们的和恰好为K。
限制条件:
1 <= n <= 20;
-10的8次方 <= a <= 10的8次方
-10的8次方 <= k <= 10的8次方

样例:
输入:n = 4; a = {1, 2, 4, 7}; k=13 输出: Yes (13 = 2 + 4 + 7)
输入: n = 4 ; a = {1 ,,2, 4, 7} ; k = 15 输出: No

图解

java代码

import java.util.ArrayList;
import java.util.Scanner;

/** 
 * @author yangshuai
 * @version 创建时间:2015-10-13 下午6:03:22 
 * 类说明 :深度优先算法
 * 给定整数a1,a2,a3...an,判断能否从中选出若干数,使他们的和恰好为K
 */
public class DESearchAlgorithm {

    /**
     * 总个数
     */
    private static int n;

    /**
     * 要求的和值
     */
    private static int k;

    private static ArrayList<Integer> a = new ArrayList<Integer>();

    private static ArrayList<Integer> result = new ArrayList<Integer>();

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.printf("请输入以下内容:\n总个数n:");
        n = scanner.nextInt();
        System.out.printf("输入a的值一共n个:\n");
        for (int i = 0; i < n; i++) {
            a.add(scanner.nextInt());
        }
        System.out.printf("要求的和值k:");
        k = scanner.nextInt();

        System.out.println("开始计算:" + System.currentTimeMillis());

        dfsAndSaveResult(0, 0, "");

        if (resultList.size() != 0){
            System.out.println("Yes");
        }else {
            System.out.println("No");
        }

        System.out.println("完成计算:" + System.currentTimeMillis());


    }

    /**
     * 不需要输出结果,只要求结论
     * @param i
     * @param sum
     * @return
     */
    static  boolean dfs(int i, int sum){

        // 如果前 i 项都计算了,则判定结果
        if (i == n) {
            return k == sum;
        }

        // 判定i+1项,不加上a[i]的情况
        if (dfs(i+1, sum)) {
            return true;
        }

        // 判定i+1项,加上a[i]的情况
        if (dfs(i+1, sum + a.get(i))) {
            result.add(a.get(i));
            return true;
        }

        return false;
    }

    /**
     * 用来存储结果
     */
    static ArrayList<String> resultList = new ArrayList<String>();

    /**
     * 验证结论,并存储各种结果
     * @param i
     * @param sum
     * @param resultString
     */
    static  void dfsAndSaveResult(int i, int sum , String resultString){

        // 如果前 i 项都计算了,则判定结果
        if (i == n) {
            if (k == sum) {
                resultList.add(resultString);
                System.out.println("第" + resultList.size() + "个结果 : "+ k + " = " + resultString.trim().replace(" ", " + "));
            }
        }else {

            // 判定i+1项,不加上a[i]的情况
            dfsAndSaveResult(i+1, sum, resultString);

            // 判定i+1项,加上a[i]的情况
            resultString += a.get(i) + " ";
            dfsAndSaveResult(i+1, sum + a.get(i), resultString);
        }

    }
}

输入样例