请问如何在一列数中找出<所有>子集,使这些子集中的元素的和为定值
比如在  int[] num = {10,123,1410, -156,258,-249,1200,73,7,-67,-53,-12};
中找出和为1234的子集
-249 -67 7 10 123 1410
-249 -53 -12 7 10 73 258 1200
...
为其中的解
这是我的做法,就是用递归来穷举,但是性能太糟糕了,差不多1分钟才算完。
各位高手有好一点的办法么?谢谢
这个问题已经困扰我好几天了。
import java.util.*;
public class test{
  int[] num = {10,123,1410, -156,258,-249,1200,73,7,-67,-53,-12};
  int sum = 0;
  boolean[] list = new boolean[num.length];
  public void f(int start,int total,boolean[] l){
    for(int i=0;i<num.length;i++){
      if(!l[i]){
        boolean[] templist = l.clone();
        int temp = total;
        temp+=num[i];
        templist[i]=true;
        if(temp==1234){
          for(int j=0;j<num.length;j++)
            if(templist[j])
              System.out.print(num[j]+" ");
          System.out.println();
        }
        else if(temp<1234){
          f(++start,temp,templist);
        }
      }
    }
  }
  public void run(){
    Arrays.sort(num);
    f(0,sum,list);
  }
  public static void main(String args[]){
    test t = new test();
    t.run();
  }
}

解决方案 »

  1.   

    Why there is no comments in your code ?
    It's difficult to understand your arithmetic(algorithm),
    Ok, if I am able to write one with nice efficency, I will paste it on.
    Good luck.
      

  2.   

    不好意思,因为这个东西基本上就一个递归的方法,所以没有写注释。
    import java.util.*;
    public class test{
      int[] num = {10,123,1410, -156,258,-249,1200,73,7,-67,-53,-12};//要算的数组
      int sum = 0;//总和
      boolean[] list = new boolean[num.length];//用于记录子集
      public void f(int start,int total,boolean[] l){
        //让数组从头至尾递归一遍
        for(int i=0;i<num.length;i++){
          //如果当前子集不包含该数字
          if(!l[i]){
            boolean[] templist = l.clone();
            int temp = total;
            temp+=num[i];
            templist[i]=true;//记录
            if(temp==1234){//等于1234就输出
              for(int j=0;j<num.length;j++)
                if(templist[j])
                  System.out.print(num[j]+" ");
              System.out.println();
            }
            else if(temp<1234){
              f(++start,temp,templist);
            }
          }
        }
      }
      public void run(){
        Arrays.sort(num);
        f(0,sum,list);
      }
      public static void main(String args[]){
        test t = new test();
        t.run();
      }
    }
      

  3.   

    f[i,j]表示用到前i个数,总和为j的方法数,类似背包
      

  4.   

    可是那样似乎不能得到全部结果。我那里的start变量就是就是用来做这个的。
    或者是我做错了,可以写一个给我么?谢谢