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

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