Java 集合子集中的数字之和

Java 集合子集中的数字之和,java,optimization,powerset,Java,Optimization,Powerset,我有一个像这样的集合S[00 01 10 11]和一个元素E11。我想找出这个集合中数字之和大于或等于元素E的数字之和的子集的数目 例如,在这种情况下,答案是10。 满足约束条件的10组为: 00 01 10 11 // Sum is 3 which is greater than 2 (sum of digits of E) 00 01 11 00 10 11 01 10 11 00 11 01 11 10 11 11 00 01 10 01 10 上述子集的所有数字之和大于或等于2(E的

我有一个像这样的集合S
[00 01 10 11]
和一个元素E
11
。我想找出这个集合中数字之和大于或等于元素E的数字之和的子集的数目

例如,在这种情况下,答案是10。 满足约束条件的10组为:

00 01 10 11 // Sum is 3 which is greater than 2 (sum of digits of E)
00 01 11 
00 10 11
01 10 11
00 11
01 11
10 11
11
00 01 10
01 10
上述子集的所有数字之和大于或等于2(E的数字之和)

我尝试了以下方法

public static void main(String[] args) {
    Set<String> inputSet = new HashSet<String>();
    Scanner sc = new Scanner(System.in);
    int N = sc.nextInt();
    int M = sc.nextInt();// specifies the length of the digts in the set.
    for (long i = 0 ; i < N; i++) {
        inputSet.add(sc.next());
    }
    long sum = 0;
    String E = sc.next();//
    sc.close();
    for (String str : E.split("(?!^)")) {
        sum = sum + Integer.parseInt(str);
    }
    List<Set<String>> subSets = new ArrayList<Set<String>>();
    for (String addToSets : inputSet) {
        List<Set<String>> newSets = new ArrayList<Set<String>>();
        for (Set<String> curSet : subSets) {
            Set<String> copyPlusNew = new HashSet<String>();
            copyPlusNew.addAll(curSet);
            copyPlusNew.add(addToSets);
            newSets.add(copyPlusNew);
        }
        Set<String> newValSet = new HashSet<String>();
        newValSet.add(addToSets);
        newSets.add(newValSet);
        subSets.addAll(newSets);
    }
    long sum1;
    long count = 0;
    for (Set<String> set : subSets) {
        sum1 = 0;
        for (String setEntry : set) {
            for (String s : setEntry.split("(?!^)")){
                sum1 = sum1 + Integer.parseInt(s);
            }
        }
        if (sum == sum1 || sum1 > sum)
            count = count+1;
    }
    System.out.println(count);
}
publicstaticvoidmain(字符串[]args){
Set inputSet=new HashSet();
扫描仪sc=新的扫描仪(System.in);
int N=sc.nextInt();
int M=sc.nextInt();//指定集合中DIGT的长度。
用于(长i=0;isum)
计数=计数+1;
}
系统输出打印项次(计数);
}
约束条件
1解决这个问题的诀窍就是要记住,
加法是关联的。所以当你加上这些数字时,其实并不重要。所以,如果我们把它简化为一个已知的问题,就很容易解决这个问题

将输入数组转换为
数字总和数组
。也就是说,如果原始数组是A,那么与结果数组B的关系将是:

          B[i] = sum of digits of(A[i]).
假设K是数字(E)的总和

然后你的问题就变成了

     Find number of subsets in B whose sum is <= K

查找B中的子集数,其和是集合中元素E的最后一个值?(试图理解你文章第1行的例子)“行不通”,这是否意味着它的内存不足?或者它运行得太慢了?我在想一个更简单的方法是子集的总数减去那些小于E的数字。。。所以2^ | set |-(numSubsetslessthandigitsE)@Adam子集的总数是2^(集合的大小)@Ivan从代码看,N是集合S的大小,M是集合S的数字长度。E是需要进行比较的元素。我希望这是有意义的。你能帮我一些伪代码或代码吗?那就更容易理解了。没有得到链接部分。@g19我已经更新了答案,这是你想要的吗?让我试试!将解决方案转换为java.Not working:(输出错误。示例案例的输出为15,但应为10.4 2 00 10 01 11
  public static void main(String[] args) {
    int[] A ={01,11,111};
    int B[] = new int[A.length];
    for(int i=0;i<A.length;i++){
        B[i]=getDigitSum(A[i]);
    }
     int E = 11;
    int K= getDigitSum(E);
    int N =B.length;
    Arrays.sort(B);
    int DP[][] = new int[B.length][B[B.length-1]+1];


    for (int i=0;i<N;i++) {
        DP[i][B[i]] = 1;

        if (i == 0) continue;

        for (int k=0;k<K;k++) {
            DP[i][k] += DP[i - 1][k];
        }
        for (int k=0;k<K;k++) {
            if( k + B[i] >= K) break ;
            DP[i][k + B[i]] += DP[i - 1][k];
        }
    }
    int sum=0;
    for(int i=0;i<K;i++) {
        sum = sum +DP[N-1][i];
    }
    int result = ((int)Math.pow(2,N)) - sum-1;
    System.out.println(result);

}

private static int getDigitSum(int num) {
    int sum =0;
    while(num >0){
       sum=sum+ (num%10);
        num= num/10;
    }
    return sum;
}