2016-05-15 1 views
4

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

Например

int[] array = {0, 24, 55, 124, 200, 259, 400, 503, 666, 797}; 

Что я должен сделать, это реализовать функцию, которая выбирает N чисел так, чтобы минимальное значение расстояния между этими отборными числами максимально.

Например, если N равно 3, то выбранные числа - 0, 400, 797, а интервалы - 400 и 397; поэтому возвращаемое значение равно 397 (которое должно быть увеличено). Если мы выберем другие наборы чисел, тогда возвращаемое значение будет меньше (или равно) 397.

Я хотел бы реализовать его с помощью рекурсии, но мне сложно его кодировать. Вы хотите мне помочь?

+0

Каков предел на $ n $? какую сложность вы ожидаете? что вы попробовали? – sashas

+3

Эта проблема уже решена. См. Следующий поток [Найти подмножество размера k, чтобы максимальное расстояние между значениями было максимально) (http://stackoverflow.com/questions/22424885/find-subset-of-size-k-such-that- the-minimum -distance-between-values-is-maximum) –

+0

Если N равно 3, вам нужно выбрать первый элемент, последний и тот, который ближе всего к средней точке, это двоичный поиск, так что это O (log (п). Для более высокого N может быть что-то подобное. –

ответ

2

Эта проблема может быть решена с использованием dynamic programing.

Если мы определим s[c][p] решением при наборе c номеров, а последнее выбранное число имеет индекс p в массиве ввода.

Мы можем затем вычислить, как s[c][p]max for i=0..p of max(s[c-1][p-i], array[p] - array[p-i])

В начале следующих состояний: s[1][0..n], где n является длиной входного массива, должны иметь значение 0.

Имея s[1][0..n], мы теперь можем легко вычислить s[2][0..n], используя данную формулу.
Имея s[2][0..n], мы теперь можем легко вычислить s[3][0..n].
И так далее ...

Решение всей проблемы было бы max s[N][N-1..n] где n длина входного массива и N это количество чисел, чтобы выбрать.

Сложность этого решения составляет O(N*n^2).
Объяснение: Рассчитываем значения для s[0..N][0..n], где каждый расчет имеет временную сложность O(n).

Сложность этого решения составляет O(n).
Объяснение: для расчета s[c][0..n] вам нужен только s[c-1][0..n], так что только 2*n памяти действительно необходимо в каждый момент времени.

EDIT: вы можете использовать рекурсию для реализации описанного алгоритма, используя технологию программирования, называемую memoization (https://en.wikipedia.org/wiki/Memoization).

+0

Спасибо! :-) – 23thMay

+0

@ 23thMay: Добро пожаловать :) –