Слишком медленное решение для разделов

Я решаю проблему, которая для меня выглядит как проблема с разбиением: у меня есть последовательность целых чисел, и я должен найти одно (если существует более одного решения, я должен вывести только одно) подмножество этих целых чисел, такое что их сумма ровно половина суммы всех целых чисел.

Я пытаюсь решить это с помощью динамического программирования, но мое решение все еще слишком медленно в тесте (я могу пройти только 2/10 тестов, а остальное слишком медленно). Спасибо за помощь.

Мой код:

void split(std::vector<int> seq, int sum, FILE * output){
  int n = seq.size() + 1;
  int m = sum + 1;
  bool** matrix = (bool**)malloc(m*sizeof(bool*));
  for(int i = 0;i<m;i++){
    matrix[i] = (bool*)malloc(n*sizeof(bool));
  }


  for(int i=1;i<=m-1;i++){
    matrix[0][i]=false;
  }
  for(int i=0;i<=n-1;i++){
    matrix[i][0]=true;
  }

  for(int i=1;i<=n-1;i++){
    for(int j=1;j<=m-1;j++){
      matrix[i][j] = matrix[i-1][j];
      if(matrix[i][j]==false && j>=seq[i-1])
    matrix[i][j] = matrix[i][j] || matrix[i-1][j-seq[i-1]];
    }
  }

  if(matrix[n-1][m-1]){
    int row = n-1;
    int column = m-1;

    while((row > 1) && (column > 0)){
      while(matrix[row-1][column]){row--;}
      fprintf(output, "%i ", row);
      column = column - seq[row-1];
    }
  }
  else{
    fprintf(output, "no");
  }
}

person user1505497    schedule 12.12.2015    source источник
comment
Не могли бы вы опубликовать несколько примеров ввода/вывода?   -  person Nick Zuber    schedule 13.12.2015
comment
например ввод: {2 3 5 6} вывод: {3 5} или {2 6}   -  person user1505497    schedule 13.12.2015
comment
Гарантированно ли отсортирован список?   -  person Nick Zuber    schedule 13.12.2015
comment
Нет, список совершенно случайный.   -  person user1505497    schedule 13.12.2015
comment
@user1505497 user1505497 Включены ли ваши вызовы ввода-вывода в вашу попытку, то есть вызов fprintf в цикле? Кроме того, вы выделяете память и никогда не освобождаете ее. Если эта функция вызывается в цикле, вы создаете огромные утечки памяти, если n и m велики.   -  person PaulMcKenzie    schedule 13.12.2015
comment
Я получаю segfault в последнем цикле while while(matrix[row-1][column]){row--;} при запуске с vector<int> v{2, 3, 5, 6}; split(v, 16);   -  person karastojko    schedule 13.12.2015


Ответы (1)


Если разрешен другой подход, вы можете попробовать использовать двоичное дерево поиска. Он должен завершиться за время O(n log n), где n — размер последовательности.

person karastojko    schedule 12.12.2015
comment
Двоичное дерево поиска объясняет концепцию. Идея для вашего случая состоит в том, чтобы сделать BST и при этом хранить в каждом узле суммы его поддеревьев. Узел с суммой половины общей суммы должен содержать все элементы. Тем не менее, я должен рассчитать, быстрее ли это, чем динамическое решение. - person karastojko; 13.12.2015
comment
Идея состоит в том, чтобы такие созданные BST шли параллельно от самого левого и самого правого узлов и проверяли суммы поддеревьев. Тем не менее, это не очень хороший подход, можно создать пример, который не может быть рассчитан таким образом. - person karastojko; 13.12.2015