Подпоследовательности

285
06 января 2018, 03:22

Дана строка1 (или ряд чисел, это не так важно) и дана строка2, которая будет являться подпоследовательностью строки1. Как можно реализовать следующее: убрать какое-то минимальное количество элементов из строки1, чтобы не получилось такой подпоследовательности? Например для строки abcdefacb и подпоследовательности acb ответом будет abcdefac. Подпоследовательностью, простым языком, можно назвать какие-то элементы, в какой-то строке или каком-то ряде, при удалении между ними элементов образуется подстрока или подряд, или подмассив (последовательность). По сути, то же, но элементы не должны обязательно быть подряд идущими.

Answer 1

Эта задача решается с помощью динамического программирования.

Сначала "на пальцах". Пусть у нас строка 2 состоит из 2 символов ab. Тогда a мы в строке 1 должны убирать сначала (сколько нужно) а символы b с конца. При это последний убранный a будет раньше чем первый убранный b (очевидно). Можно уже начинать перебирать границу раздела, поддерживая число символов (за линейно).

Что делать, если строка длиннее. Для простоты понимания с конца. Пусть мы уже взяли предпоследний (N-1) символ строки 2 и он перешёл в j строки 1. Тогда мы должны удалить все последние (N) символы строки 1. Заполнили массив F[N-1][j]. Теперь пусть мы расставили N-2 символов. Используя идею из упрощения с 2 символами мы можем перебрать точку оптимальности (выбрать отрезок [j,k] такой что число элементов равный N на нём плюс F[N-1][k] будет минимально). Так мы получили F[N-2][j]. Повторять N раз.

При правильной реализации сложности будет квадратичная. Если не получается за квадрат - пишите за куб.

P.S. я надеюсь оптимальнее по времени это решать нет необходимости (это возможно).

Answer 2

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

Есть строка "21212122" и подстрока "121"

Для начала посчитаем и запомним позиции вхождения подстроки. У нас есть 2 вхождения на позиции 1 и 3(отсчет от 0). Длинна подстроки 3(121). Для каждого вхождения проверяем цепляем ли мы следующее вхождение.

1(вхождение) + 3(длинна подстроки) -1(отсчет от нуля) = 3
А 3 <= 3(следующие вхождение) Значит удаляем 3 символ. Иначе удаляем любой (допустим 1). И так перебираем все вхождения.

Таким образом мы удалим минимальное количество символов из последовательности

Другой вариант перебором. Находим все вхождения. Идем циклом по вхождениям. Перебором удаляем по 1 символу, затем по 2, итд и проверяем как изменилась строка. В конце перебора удаляем наилучший вариант и идем к следующему вхождению

READ ALSO
sharedptr C++(падает программа)

sharedptr C++(падает программа)

Здравствуйте, использую в программе std::shared_ptr и программа начинает себя вести по странномуУ меня программа БД для школы и вот при добавлении...

238
задачи на палиндромы

задачи на палиндромы

В первой строке входных данных содержится число N (1 <= N <= 100000)Во второй строке задается последовательность из N больших латинских букв (буквы...

219
Выбор кандидатов при вызове функций

Выбор кандидатов при вызове функций

Почему в следующем коде std::swap не рассматривается в качестве кандидата при вызове swap и приходится писать его полностью с пространством имён?...

230
Рефакторинг кода в Qt (C++)

Рефакторинг кода в Qt (C++)

Здравствуйте, задался довольно-таки очень простым вопросом

552