Условие:
Есть скобочная последовательность - строка из не более чем 100 символов.
Содержит символы: '[' , ']' , '(' , ')'
Нужно вставить в неё минимальное количество символов так, чтобы получилась
правильная скобочная последовательность и вывести эту последовательность.
Что такое правильная скобочная последовательность (далее СП) ?
1) Пустая СП является правильной
2) [A] и (A) - правильные СП, если А - правильная СП
3) АВ - правильная СП, если А и В - правильные СП
Теперь как решать задачу.
Если бы мы знали для исходной строки самую длинную подпоследовательность, являющуюся правильной СП, то
дополнив не вошедшие в неё скобки до правильных СП вида [] или () мы бы получили ответ.
Следовательно, задачу можно переформулировать:
Найти самую длинную подпоследовательность, являющуюся правильной СП.
Введем числовую характеристику размера правильной СП - назовем ее D - пусть это будет количество пар вида [] или () из которых она образована.
(но можно взять и количество символовв ней, разница несущественная).
Давайте рассмотрим нашу СП. Как рассчитать для неё D? Пусть в нашей СП есть некоторая пара скобок расположенных как на примере ниже.
(пара открывающая-закрывающая одного типа, далее ОЗ)
пример:
**(**)**** - последовательность (* - любая скобка)
0123456789 - нумерация элементов
если такой пары нет, то правильной СП тут тоже нет
Тогда D для всей последовательности - Dp = Dl+Dm+Dr+1
Dl - для отрезка слева [1,2]
Dr - для отрезка справа [6,9]
Dm - посередине [3,4]
+1 т.к. мы закрепили 2 скобки, являющиеся правильной СП и они тоже должны быть учтены
Всё бы ничего только, эта зависимость несовсем корректная. Она не учитывает вложенности скобок. (контртест придумайте сами)
Выход в следующем: Переберём все такие пары ОЗ скобок, посчитаем D по формуле выше и найдём максимум.
Это и будет ответ для нашей строки. (предлагаю вам самим доказать, что Dl можно исключить из формулы, двух слагаемых и перебора достаточно).
Таким образом, мы получили рекурсивную зависимость ответа для подстроки длинной N от подстрок с длинной L < N.
Но если это так и реализовать, рекурсивно, то время работы такого решения будет просто жутким.
Поэтому дальше переходим к банальной динамике.
Будем искать D для всех подстрок с i-го по j-й элементы.
В порядке возрастания длинны подстроки и сохранять все результаты в двухмерном массиве.
D[i][j] - ответ для подстроки с i-го по j-й элемент.
перебираем длину {
перебираем стартовую позицию{
двойным циклом ищем D.
}
}
Итак, мы знаем, какова максимальная длина правильной скобочной подпоследовательности в каждой подстроке.
Осталось собрать и вывести ответ.
Возьмем нашу строку, и найдем в ней любую пару ОЗ скобок, такую что D подстроки внутри этой пары + D справа + 1 == D всей строки.
Красим эту пару ОЗ скобок, как вошедшие в максимальную СП нашей строки и по этому же принципу
рекурсивно обрабатываем отрезок между только что покрашенными скобками и отрезок справа от них.
Вспоминаем начало заметки:
"ЕСЛИ БЫ МЫ ЗНАЛИ для исходной строки самую длинную подпоследовательность, являющуюся правильной СП, то
дополнив не вошедшие в неё скобки до правильных СП вида [] или () мы бы получили ответ."
Теперь знаем.
Оценка сложности решения:
Память О(N^2) - очевидно, двухмерный массив.
Время О(N^4) - цикл заполнения массива
Причем константа перед N^4 a << 1.