nyoj_1058(简单搜索)

题目描述如下:
描述
给定整数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

take notes:
解法一:按照全排列的思想,将dfs写在for循环里面,先选1 2 4 7,发现超过k要求的数之后回溯,用一个book数组做标记,如果没有用过的可以用,用过的数只能向下走找到一个没用过的数,进行运算。这样写只能求一种情况,若答案有多种,要用解法二。

import java.util.Scanner;

public class Main {
static int n,k;
static boolean flag = false;
static int[] ans = new int[20];
static int[] book = new int[20];
static void dfs(int x,int sum){
    if(sum==k){ 
        flag=true;

        return;
    }
    if(sum>k){      
        return;
    }
    else{
        for(int i=0;i<n;i++){
            if(book[i]==0){
                book[i]=1;
                dfs(x+1,sum+ans[i]);
                if(flag==true)return;
                book[i]=0;
            }
        }
    }
}
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner in = new Scanner(System.in);
        n=in.nextInt();
        k=in.nextInt();

        for(int i=0;i<n;i++){
            ans[i] = in.nextInt();
        }
        dfs(0,0);
        if(flag==true){
            System.out.println("YES");
            for(int i=0;i<n;i++){
                if(book[i]==1){
                    System.out.print(ans[i]+" ");
                }
            }
        }
        else System.out.println("NO");

    }

}

解法二:可以解出多种答案,不需要for循环和book数组,而是需要一个新的数组来存放满足条件的答案,中心思想就是,当前这个数要还是不要,如果要则应该加在sum中,若不要则减掉,但是无论要还是不要x都要加一,也就是都要往后走,通过存放结果的数组的下表m–来实现回溯,这里重点要注意,dfs里面的参数不要动!

import java.util.Scanner;

public class Main {
static int n,k,m;
static int[] ans = new int[20];
static int[] bns = new int[20];
static boolean flag = false; 
static void dfs(int x,int sum){
    if(sum==k){
        System.out.println("YES");
        for(int i=0;i<m;i++){
            System.out.print(bns[i]+" ");
        }
        System.out.println();
        flag=true;
        return;
    }
    if(sum>k ||x==n){
        return;
    }
    else{
    sum=sum+ans[x];     
    bns[m]=ans[x];
    m++;    
    dfs(x+1,sum);   
    m--;
    sum=sum-ans[x];

    dfs(x+1,sum);
    }
}
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner in = new Scanner(System.in);
        n=in.nextInt();
        k=in.nextInt();
        for(int i=0;i<n;i++){
            ans[i]=in.nextInt();
        }
        m=0;
        dfs(0,0);
        if(flag==false)System.out.println("NO");
    }

}

分享一组样例
输入
4 13
3 10 4 6
输出
YES
3 10
YES
3 4 6

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章