ACM - Псков

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » ACM - Псков » Timus » Timus 1183


Timus 1183

Сообщений 1 страница 2 из 2

1

Условие:
Есть скобочная последовательность - строка из не более чем 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.

2

Ну решение близко к хорошему, но неоптимальное.
За N^3 можно.
Достаточно заметить, что не надо перебирать пару скобок откуда-то изнутри, а всегда брать ту пару скобок, которая стоит в начале отрезка (ну открывающая скобка стоит первой).

Переходы у меня такие:
d[l][r]:
если s[l] - закрывающая скобка, то слева от неё ставим открывающую, переходим в d[l+1][r]
если s[l] - открывающая скобка, то переберём, где стоит закрывающая для неё.
перебираем k=l..r, если там уже стоит закрывающая скобка, то используем её, переходим в d[l+1][k-1] + d[k+1][r].
если же там стоит другая скобка, то ставим туда нужную нам, переходим в 1 + d[l+1][k] + d[k+1][r]


Вы здесь » ACM - Псков » Timus » Timus 1183