Как вывести все самые длинные снижения последовательности
-
16-10-2019 - |
Вопрос
Предположим, у меня есть множество целых чисел, имеющих длину $ n $. Как я могу вывести все самые длинные снижения последовательности? (Последующая последовательность состоит из элементов массива, которые не должны быть последовательными, например, $ (3,2,1) $ - это снижение последующей последующей последовательности (7,3,5,2,2,0,1) $.) Я знаю, как вычислить длину самых длинных последовательностей, но не знаю, как сообщать о всех самых длинных последовательностях.
Псевдокод будет полезен.
Решение
Рассмотрим следующую последовательность в качестве ввода:
$$ N, N-2, N-1, N-3, N-5, N-4, N-6, N-8, N-7, N-9, ...., N-3 CDOT k - 2, n -3 cdot k - 1, n -3 cdot k - 3, .... $$
Для простоты предположим, что $ n = 3 cdot t + 1 $, самое длительное уменьшение длины последующей последовательности будет $ t $, а количество уменьшения последующей длины $ t $ составляет 2 доллара $.
Таким образом, количество выдающихся решений - $ theta (2^{n/3}) $. Но почему так, просто моделируйте его с DAG, будьте осторожны, есть преимущество от $ A $ → $ B $, если $ A> B $ и $ B $ после $ A $ в оригинальной последовательности.
Таким образом, поскольку выходной размер может быть экспоненциальным, ваш лучший выбор - создание DAG и поиск всех самых длинных путей в DAG или любых других способов, которые перечисляют все приемлемые способы.
Другие советы
-рекурсивная вспомогательная функция
list form_longest_sublist_from(list array,list buffer,from)
add array[from] to buffer
list ret as copy of buffer
from i = from - 1 to -1 step -1
if last buffer > array[i]
list sbuffer
sbuffer = form_longest_sublist_from(array,buffer,i);
if length sbuffer > length ret
ret = sbuffer;
endif
endif
endfor
return ret;
endfunc
Алгоритм использования функции
list of lists arrayoflongestlist list buffer; from i = length array - 1 to -1 step -1 clear buffer add array[i] to buffer from x = i - 1 to -1 step -1 if(array[x] < last buffer list sbuffer; sbuffer = form_longest_sublist_from(array,buffer,x); if length sbuffer > length buffer) buffer = sbuffer; endif endif endfor if length arrayoflongestlist > 0 if length (last arrayoflongestlist) < length buffer clear arrayoflongestlist add buffer to arrayoflongestlist endif else if length (last arrayoflongestlist) == length buffer add buffer to arrayoflongestlist endif if length (last arrayoflongestlist) > i) break; else add buffer to arrayoflongestlist endif endfor
Я в основном поменял весь алгоритм, чтобы подходить для проблемы.
Основная идея состоит в том, чтобы начать с каждой возможной точки (каждый элемент) в массиве и сформировать все возможные уменьшения сублистов с того, что выходили из остальной части массива и посмотрите, какие элементы меньше, и используют эти элементы, чтобы начать рекурсию, которая делает то же самое упомянутое Перед началом этого момента, а затем фильтруют рекурсии для самого длинного списка, отданного.
Мои возможные худшие сценарии, упомянутые ранее, приводятся в действие, учитывая этот алгоритм.
Для каждой снижения последовательности храните начальные позиции в другом массиве.
for( i = 0; i < n-1; i++ ) {
if ( a[i] > a[i+1] ) {
temp[j++] = i;
while( a[i] > a[i+1] ) {
i++;
}
temp[j++] = i;
}
}
Теперь температура массива будет содержать начальные и конечные позиции всех уменьшающихся последовательностей последовательно. Затем распечатайте их