設集合S={x1,x2,…,xn}是一個正整數集合,c是一個正整數,子集和問題斷定是否存在S的一個子集S1,使S1中的元素之和爲c。試設計一個解子集和問題的回溯法。java
輸入數據第1行有2個正整數n和c,n表示S的大小,c是子集和的目標值。接下來的1行中,有n個正整數,表示集合S中的元素。 是子集和的目標值。接下來的1 行中,有n個正整數,表示集合S中的元素。算法
輸出子集和問題的解,以空格分隔,最後一個輸出的後面有空格。當問題無解時,輸出「No Solution!」。設計
在這裏給出一組輸入。例如:code
5 10 2 2 6 5 4
在這裏給出相應的輸出。例如:遞歸
2 2 6
本題要求只輸出第一個解,並採用回溯法,因此能夠主體來枚舉全部狀況,而後再剪枝剪掉不須要的分支:io
package 宿題;
import java.io.*;
public class PTASubsetSum {
static int c;
static int n;
static boolean Out=true;//這裏新建一個標記位,用來記錄有無第一個解出現,結束遞歸;
public static void main(String args[])throws IOException{
StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));//當須要輸入大量數據時BufferedReader處理速度快,比Scanner高效;
in.nextToken();
n=(int)in.nval;
in.nextToken();
c=(int)in.nval;
int a[]=new int[n];
int SUM=0;
for(int i=0;i<n;i++){
in.nextToken();
a[i]=(int)in.nval;
SUM+=a[i];//減去當全部數和小於c時的分支;
}
if(SUM>=c){
Count(a,0,0,"");
if(Out)
System.out.println("No Solution!");
}else
System.out.println("No Solution!");
}
private static void Count(int a[],int count,int sum,String s){
if(count<n&&Out){
if(sum+a[count]==c){
Out=false;//結束遞歸;
System.out.println(s+a[count]+" ");
}else if(sum+a[count]<c){//分支向下求解;
Count(a,count+1,sum+a[count],s+a[count]+" ");
System.out.println(s+a[count]+" ");
}
Count(a,count+1,sum,s);
System.out.println(s);
}
}
}class
該算法最壞情形下時間複雜度爲O(2^n)。import