Главная страница


ru.algorithms

 
 - RU.ALGORITHMS ----------------------------------------------------------------
 From : Serge Kanilo                         2:5020/400     24 May 2001  02:03:29
 To : All
 Subject : Re: a[i1]+a[i2]+...+a[ik] = N*p
 -------------------------------------------------------------------------------- 
 
 "Ihor Bobak" <ihor@bulgaria.com> wrote in message
 news:9eh5hk$1enu$1@gavrilo.mtu.ru...
 
 > Есть такая задача: дано масив N чисел a[1], a[2],..., a[N].
 > Из него нужно выбрать такое подмножество из k<=N элементов, чтобы
 > a[i1] + a[i2] + ... + a[ik] делилось на N (если такое подмножество
 > существует вообще)
 > Так как N может быть довольно большим (около 10000), то перебор в
 > лоб (то есть "брать элемент - не брать") дающий сложность О(2^N) есть
 > недопустимым.
 
 Пару месяцев назад проходила очень близкая к данной задача
 но "попроще" - определить множество чисел, сумма которых равна N.
 Hа практике хорошо построенный перебор с отсечением явно
 неправильных вариантов позволяет решить такую задачу
 достаточно быстро.
 Для целых чисел можно сделать алгоритм прямо для данной
 задачи сложности N^3.
 
 1) Определяем битовый массив, который будет хранить
 всевозможные суммы элементов. Элемент массива true,
 если существует сумма (вернее сумма%N) равная индексу.
 
 bool s[N];
 
 2) Инициализируем. Все элементы false, поскольку нет элементов.
 
 for(int i=0; i<N; i++) s[i]=false;
 
 2) Для каждого числа из множества (я предположил, что не всегда
 число элементов соответствует сумме)
 
 int i;
 for(i=0; i<K; i++){
 
 2.1) Делаем циклический сдвиг массива на a[i] элементов, что
        соответствует всем предыдущим суммам плюс данный элемент
 
   bool r[N];
   for(int j=0; j<N; j++) r[(i+a[i])%N]=s[i];
 
 2.2) Объелиняем с исхожным массивом, ведь можем этот элемент
   и не добавлять
 
   for(int j=0; j<N; j++)if(r[j]) s[j]=true;
 
 2.3) Добавляем данный элемент.
 
   s[a[i]%N] =true;
 
 2.4) Проверяем, есть ли сумма кратная N, т.е. нулевой элемент (или N%N-й,
 кому что нравится :) и если да, то заканчиваем
 
   if(s[0]) break;
 
   }
 
 3) Если цикл закончен по 2.4, то известно, что a[i] входит в сумму,
 поэтому перейдем к аналогичной задаче для суммы N-a[i] и первых
 i-1 элементов. Делается внешним циклом или рекурсией.
 Таким образом сложность в случае неуспеха - K*N,
 в случае успеха - K^2*N.
 
 Hекоторого ускорения возможно можно достичь
 пересортировкой элементов по убыванию a[i]%N.
 
 Cheers,
 
 Serge
 
 --- ifmail v.2.15dev5
  * Origin: Excite@Home - The Leader in Broadband http://home.com/f (2:5020/400)
 
 

Вернуться к списку тем, сортированных по: возрастание даты  уменьшение даты  тема  автор 

 Тема:    Автор:    Дата:  
 a[i1]+a[i2]+...+a[ik] = N*p   Ihor Bobak   24 May 2001 00:20:59 
 Re: a[i1]+a[i2]+...+a[ik] = N*p   Serge Kanilo   24 May 2001 02:03:29 
 Re: a[i1]+a[i2]+...+a[ik] = N*p   Andrey Dashkovsky   24 May 2001 20:42:26 
 RE: a[i1]+a[i2]+...+a[ik] = N*p   Andrey Popyk   25 May 2001 10:36:04 
 a[i1]+a[i2]+...+a[ik] = N*p   Victor Petrov   25 May 2001 11:22:52 
Архивное /ru.algorithms/210676f54a04f.html, оценка 3 из 5, голосов 10
Яндекс.Метрика
Valid HTML 4.01 Transitional