Форум программистов, компьютерный форум, киберфорум
Алгоритмы
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
0 / 0 / 0
Регистрация: 25.02.2020
Сообщений: 10
1

Минимальная сумма расстояний между каждым элементом массива и множествами из к-элементов этого массива

07.02.2021, 20:08. Показов 1869. Ответов 8

Author24 — интернет-сервис помощи студентам
Всем привет. Еще одна модификация одной из самых распространённых задач.
(Минимальная сумма абсолютных разностей между элементом и подмножеством элементов массива)

У нас есть целочисленный неотсортированный массив положительных чисел.
Для каждого элемента массива нужно найти минимальную сумму расстояний от этого элемента до множества элементов массива размера К, не содержащих этот элемент.

То есть:
Массив = {5, 7, 4, 9}
К = 2

min_sum(5) = dist(5, {4, 7}) = |5-4|+|5-7|=3
min_sum(7) = dist(7, {9, 5}) = |7-9|+|7-5|=4
min_sum(4) = dist(4, {5, 7}) = |4-5|+|4-7|=4
min_sum(9) = dist(9, {7, 5}) = |9-7|+|9-5|=6

Наивным решением было бы отнять от всех элементов массива i-тый элемент, затем отсортировать такой массив и посчитать суммы первых К элементов в отсортированном массиве. И так для каждого индекса. Но это работает только для маленьких массивов...

Если сперва отсортировать массив, тогда можно будет рассматривать только +-К элементов вокруг i-того элемента. Но К может быть размера вплоть до размера самого массива.

Можно хранить массив разностей между элементами отсортированного массива, но не понимаю можно ли это использовать эффективно.

Ограничение на входные данные:
n - количество элементов массива
k - размер подмножеств
a[i] - элемент массива

2 <= n <= 350 000
1 <= k < n
1 <= a[i] <= 10^9

Ограничение по времени: 2 сек.

С таким ограничением нужно как-то решить эту задачу быстрее, чем за O(n^2)

Буду благодарен, если у кого-нибудь есть идея, как это можно реализовать эффективно, какие структуры данных использовать лучше.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.02.2021, 20:08
Ответы с готовыми решениями:

Сумма элементов массива, расположенных между первым и последним элементом
#include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &quot;conio.h&quot; #include &lt;stdio.h&gt; #include...

Сумма элементов между первым и последним отрицательным элементом массива.
Не могу посчитать суму междк первым и последним отрицательным! а также нужно переобразовать...

Сумма элементов массива, расположенных между первым и последним положительным элементом
Вычислить сумму элементов массива, расположенных между первым и последним положительными...

Сумма элементов между первым положительным элементом массива и последним отрицательным
В одномерном целочисленном массиве( элементы массива генерируются случайным образом диапазоне от...

8
646 / 522 / 72
Регистрация: 20.09.2014
Сообщений: 3,356
08.02.2021, 21:54 2
Цитата Сообщение от Timur Abdullaev Посмотреть сообщение
Если сперва отсортировать массив, тогда можно будет рассматривать только +-К элементов вокруг i-того элемента. Но К может быть размера вплоть до размера самого массива.
Ну и что, что K ~ n? Это же проблема не только для алгоритма с предварительной сортировкой, но и любого другого, какой придумаете. Начинайте уже кодить с сортировкой!
0
Модератор
Эксперт функциональных языков программирования
3051 / 2193 / 459
Регистрация: 26.03.2015
Сообщений: 8,469
09.02.2021, 11:37 3
Цитата Сообщение от Timur Abdullaev Посмотреть сообщение
min_sum(7) = dist(7, {9, 5}) = |7-9|+|7-5|=4
Где тут искомый массив размера К? Или исходный массив "зациклен"?

Добавлено через 5 минут
Или можно выбрать любые К из оставшихся элементов, даже если они расположены не рядом?
0
Эксперт Python
8213 / 4333 / 1837
Регистрация: 27.03.2020
Сообщений: 7,154
09.02.2021, 14:37 4
Наивным решением было бы отнять от всех элементов массива i-тый элемент, затем отсортировать такой массив и посчитать суммы первых К элементов в отсортированном массиве. И так для каждого индекса. Но это работает только для маленьких массивов...
numpy - для 10^7 элементов массива обработка меньше 1 сек для любого "k"
0
0 / 0 / 0
Регистрация: 25.02.2020
Сообщений: 10
11.02.2021, 15:33  [ТС] 5
Цитата Сообщение от Mikhaylo Посмотреть сообщение
Начинайте уже кодить с сортировкой!
Посмотрите на ограничение по времени сначала. Это задание не тупо на "кодирование", а на "алгоритмы".

Добавлено через 3 минуты
Цитата Сообщение от Shamil1 Посмотреть сообщение
Или можно выбрать любые К из оставшихся элементов, даже если они расположены не рядом?
Да, для каждого элемента массива можно выбирать любые К из оставшихся.

Добавлено через 3 минуты
Цитата Сообщение от Gdez Посмотреть сообщение
numpy - для 10^7 элементов массива обработка меньше 1 сек для любого "k"
Нельзя использовать сторонние библиотеки. Да и не может numpy так быстро считать, вы наверно находите только для 1 элемента массива, а надо для каждого, для N. C решением в лоб - это 10^10 операций. Решение на С++ отрабатывает за 2 минуты при N=350000, K= 150000.
0
646 / 522 / 72
Регистрация: 20.09.2014
Сообщений: 3,356
11.02.2021, 21:31 6
Отсортируйте массив. Рассмотрим некоторое фиксированное K. Пусть для данного K уже посчитана минимальная сумма некоторого числа q, т.е. известно min_sum(q, K). Также для данной пары (q, K) известно число элементов element_count, которые при вычислении min_sum были больше числа q. Тогда легко вычислить, что количество элементов, которые были меньше q, равно (K - element_count(q, K)).

Пусть надо найти min_sum(p, K), где p входит в множество оптимальных соседей числа при вычислении min_sum(q, K).
Так как числа p и q расположены достаточно близко, то наверняка у них достаточно большой набор общих оптимальных соседей. Самое худшее, что может случиться, это то, что числа p и q имеют близкие индексы, но очень большой разрыв по значениям. В этом случае среди оптимальных соседей чисел p и q может не оказаться ни одного общего. Но нет худа без добра, так как любой такой разрыв хоть и отдаляет числа p и q, но "сближает" числа p и r, если они находятся по одну сторону разрыва.

Пересчитываем min_sum*(p, K) = min_sum(q, K) + (p - q) * (K - element_count(q, K)) + (p - q) * element_count(q, K), где min_sum*(p, K) - это минимальная сумма для числа p, при условии, что у пар (q, K) и (p, K) множества оптимальных соседей совпадают. Далее мы пересчитываем min_sum*(p, K), сдвигая множество оптимальных соседей влево или вправо на один индекс в сторону числа p от числа q и проверяя, не нашли ли мы более оптимальное множество. Делаем это, пока min_sum перестало уменьшаться или число q не оказалось на краю этого множества.

Добавлено через 14 минут
Пересчет min_sum(p, K) через min_sum(q, K) по предлагаемому алгоритму занимает не K шагов как в случае вычисления в лоб, а от 1 до K.
Например, для равномерного распределения чисел алгоритм сработает за время O(n). Можно показать, что наихудшее время составляет O(n^2/K). А вы так боялись этого K.

Добавлено через 49 секунд
Могу в деталях ошибаться.
1
Модератор
Эксперт функциональных языков программирования
3051 / 2193 / 459
Регистрация: 26.03.2015
Сообщений: 8,469
12.02.2021, 10:47 7
После сортировки массива нужно пройтись по нему один раз.
У нас два курсора. Один указывает на текущий элемент (для которого мы вычисляем минимальную сумму). Второй - "окно" - указывает на границы подмассива размером К+1.
Так как оба курсора могут двигаться только вперёд, мы пройдём по массиву за О(n). Продвижение второго курсора останавливается, когда его правая граница совпадёт с правой границей массива.

1. Для первого элемента лучшим "окном" будут первые К+1 элементов. (Включение самого элемента не влияет на сумму, так как "расстояние до себя" равно нулю).

2. Выбираем следующий элемент и за О(1) вычисляем сумму расстояний для текущего "окна".

3. (Если правая граница окна не достигла правой границы массива И левая граница окна не достигла текущего элемента)
За О(1) вычисляем сумму расстояний до следующего "окна".
Если эта сумма меньше, то сдвигаем "окно". Повторяем 3.
Если эта сумма больше, то записываем минимальную сумму для текущего элемента и переходим к следующему (пункт 2).
0
0 / 0 / 0
Регистрация: 25.02.2020
Сообщений: 10
15.02.2021, 04:01  [ТС] 8
Цитата Сообщение от Mikhaylo Посмотреть сообщение
min_sum*(p, K) = min_sum(q, K) + (p - q) * (K - element_count(q, K)) + (p - q) * element_count(q, K)
Думаю, что должно быть: min_sum*(p, K) = min_sum(q, K) + (p - q) * (K - element_count(p, K)) - (p - q) * element_count(p, K)
А затем эту сумму модифицируем, сдвигая границы только влево или только вправо, смотря, где сумма меньше.
0
646 / 522 / 72
Регистрация: 20.09.2014
Сообщений: 3,356
16.02.2021, 04:57 9
Цитата Сообщение от Timur Abdullaev Посмотреть сообщение
Думаю, что должно быть: min_sum*(p, K) = min_sum(q, K) + (p - q) * (K - element_count(p, K)) - (p - q) * element_count(p, K)
Ну да.

Цитата Сообщение от Timur Abdullaev Посмотреть сообщение
А затем эту сумму модифицируем, сдвигая границы только влево или только вправо, смотря, где сумма меньше.
Я обобщил на почти произвольные числа p и q, то есть развил целую теорию. Но на практике проще взять соседние числа, об этом сказал Шамиль.
0
16.02.2021, 04:57
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
16.02.2021, 04:57
Помогаю со студенческими работами здесь

Сумма элементов, расположенных между первым четным элементом массива и последним
В массиве целых чисел найти сумму элементов, расположенных между первым четным элементом и...

Сумма элементов массива, расположенных между первым и последним положительным элементом
В одномерном массиве, состоящем из n вещественных элементов, вычислить: 1) минимальный элемент...

Массив. Найти количество элементов массива, лежащих между 1-м элементом массива и элементом с номером Х
Для массива,содержащего 8 чисел.Найти количество элементов массива,лежащих между 1-м элементом...

Составить массив А1, каждый элемент которого равен разности между соответствующим элементом массива А и средним арифметическим этого массива
Массив А состоит из 20 элементов. Составить массив А1, каждый элемент этого массива вычислить как...

Дан массив А(20). Найти разницу между каждым элементом массива и средним арифметическим
Дан массив А(20). Найти разницу между каждым элементом массива и средним арифметическим.

Сравнение элементов массива с предыдущим элементом этого массива
По заданию нужно сделать так, чтобы программа выводила сумму при неубывающей последовательности и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru