Сумма цифр в подмножестве набора

У меня есть набор 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);
}

Ограничения 1 ‹= N ‹= 10^5


1 <= M <= 20

Приведенный выше подход не будет работать для размеров наборов в диапазоне 105. Пожалуйста, помогите обеспечить эффективный подход для этого. Спасибо!


person g19    schedule 09.07.2015    source источник
comment
ЯВЛЯЕТСЯ ли элемент E в вашем наборе последним значением? (Попытка понять пример в строке 1 вашего поста)   -  person Norbert van Nobelen    schedule 09.07.2015
comment
Не сработает. Означает ли это, что ему не хватает памяти? Или он работает слишком медленно?   -  person Ivan    schedule 09.07.2015
comment
Я думаю, что более простой подход - это общее количество подмножеств за вычетом тех, которые меньше цифр E... так что 2 ^ | набор | - (numSubsetslessthandigitsE)   -  person Adam    schedule 09.07.2015
comment
@Adam общее количество подмножеств равно 2 ^ (размер набора)   -  person pvg    schedule 09.07.2015
comment
@пвг. Я знаю. Мой комментарий не был сделан.   -  person Adam    schedule 09.07.2015
comment
Являются ли 1 и 0 единственными разрешенными цифрами в наборе? Все ли элементы состоят из двух цифр?   -  person pvg    schedule 09.07.2015
comment
@Ivan Он работает слишком медленно.   -  person g19    schedule 09.07.2015
comment
@NorbertvanNobelen 9-я строка моего кода — это элемент E.   -  person g19    schedule 09.07.2015
comment
@adam, тогда вы можете видеть, как этот подход не может ответить на вопрос - 2 ^ 10000 - это больше подмножеств, чем элементарных частиц во Вселенной, на много порядков.   -  person pvg    schedule 09.07.2015
comment
@pvg Да, разрешены только цифры 1 и 0. Нет, все элементы не состоят из двух цифр. Они могут быть длинными до 20 цифр. Я отредактировал свой код. Переменная M определяет длину цифры.   -  person g19    schedule 09.07.2015
comment
@g19 g19, может, тебе стоит просто опубликовать вопрос о домашнем задании, раз это звучит как домашнее задание? Трудно ответить, если вы пропустите ключевые ограничения. Очевидно, что речь идет о поиске решения, которое не требует создания всех мыслимых подмножеств, и это очень сильно зависит от того, как определяется исходное множество.   -  person pvg    schedule 09.07.2015
comment
@pvg Я добавил ограничения. Пожалуйста, проверьте, имеет ли это смысл для вас :)   -  person g19    schedule 09.07.2015
comment
Что такое N и M по отношению к S и E?   -  person Ivan    schedule 09.07.2015
comment
@Ivan Из кода кажется, что N - это размер набора S, а M - длина цифр набора S. E - элемент, с которым необходимо провести сравнение. Я надеюсь это имеет смысл.   -  person bane19    schedule 09.07.2015
comment
Я сомневаюсь, что у него будет 2 ^ 10000 подмножеств. Будь реальным.   -  person Adam    schedule 09.07.2015


Ответы (1)


Загвоздка в решении этого вопроса просто помнить, что addition is associative. Поэтому, когда вы добавляете эти цифры, это не имеет большого значения. Итак, если мы сведем это к известной проблеме, ее легко решить.

Преобразуйте свой входной массив в sum of digits array. То есть, если ваш исходный массив A, то отношение к вашему результирующему массиву B будет:

          B[i] = sum of digits of(A[i]).

Скажем, К — это sum of digits(E)

Тогда ваша проблема сводится к

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

Что легко.

ИЗМЕНИТЬ:

  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;
}
person Karthik    schedule 09.07.2015
comment
Можете ли вы помочь мне с псевдокодом или кодом? Тогда будет легче понять. Не получается часть ссылки. - person g19; 09.07.2015
comment
@ g19 Я обновил ответ. Это то, о чем вы просили? - person Karthik; 09.07.2015
comment
Дай попробовать! Преобразование решения в java. - person g19; 09.07.2015
comment
Не работает :( Неправильный вывод. Вывод 15 для примера, но должен быть 10. - person bane19; 09.07.2015
comment
Не могли бы вы помочь мне перевести его на Java или помочь мне с тем же. - person g19; 09.07.2015
comment
@ g19 попробуйте этот код, я проверил его с несколькими тестовыми примерами. Оно работает. - person Karthik; 09.07.2015
comment
@g19 Я рад, что это помогло :) - person Karthik; 09.07.2015