Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cmath>
- #include<vector>
- #include<map>
- #include<set>
- #include<algorithm>
- #include<string>
- #include <queue>
- #include<stack>
- #include<deque>
- #include<fstream>
- using namespace std;
- ifstream fin("input.txt");
- ofstream fout("output.txt");
- int dp[103][103];
- string ss[103][103];
- bool isa(char a, char b) /// Проверка валиности двух скобок
- {
- if (a == '['&&b == ']')
- return true;
- if (a == '('&&b == ')')
- return true;
- if (a == '{'&&b == '}')
- return true;
- return false;
- }
- bool combo(char a, char b, char c, char g)
- {
- return (isa(a, b) && isa(c, g));
- }
- int main()
- {
- string s;
- fin >> s;
- int n;
- n = s.size();
- int ansmax = 0;
- string ans;
- for (int i = 1; i <= n; i++) /// i представляет собой : длину разбираемой последовательности минус 1.
- {
- for (int j = 0; j < n - i; j++) /// j - стартовая точка
- {
- int mx = 0; /// нахуй не нужная переенная
- /// ( { ( ) ) - возьмем к примеру такую скбчн послед
- for (int l = j; l < j + i; l++) /// перебираем так называемый разделитель последовательностей. Допустим это будет символ X
- {
- /// так как разделитель делит на 2 составные ,ему нужно как минимум 4 скобки -> ( { X ( ) )
- int r = l + 1;
- if (l == j) /// Но если наш раздедитель отделяет только первую скобку , то тут требуется костыль ( X { ( ) )
- {
- if (dp[r][j + i] > dp[j][j + i]) /// Можно заметить , что тут нет проверки на валидность скобок , так как , к примеру , для отрезка 2-6 , ответ будет () ---- мы его получаем в 80 строчке в дп
- {
- dp[j][j + i] = dp[r][j + i];
- ss[j][j + i] = ss[r][j + i];
- }
- }
- if (r == j + i) /// тоже самое с послдней скобкой ( { ( ) X )
- {
- if (dp[j][l] > dp[j][j + i])
- {
- dp[j][j + i] = dp[j][l];
- ss[j][j + i] = ss[j][l];
- }
- }
- if (dp[j][l] + dp[r][j + i] > dp[j][j + i]) /// Теперь нормальная ситуация
- { /// Пример для перебора разделителя на последнем шагу : ( { X ( ) ) , ( { ( X ) )
- dp[j][j + i] = dp[j][l] + dp[r][j + i];
- ss[j][j + i] = ss[j][l] + ss[r][j + i];
- }
- /// К примеру : ( { X ( ) ) предполагает что мы обьеденим
- /// --- эту часть
- /// ---- и эту , получив общий ответ для дух отрезков : "" + "()"
- }
- /// последняя часть, на которой и строится решение
- if (dp[j + 1][j + i - 1] + isa(s[j], s[j + i]) > dp[j][j + i]) { /// Ответ для нашего отрезка - это ответ для отрезка с длинной -2 ( dp[j+1][j+i-1] и +1 в случае
- ///если наша скобочная последовательность валидна
- dp[j][j + i] = dp[j + 1][j + i - 1] + isa(s[j], s[j + i]); /// добовляем к ответу
- ss[j][j + i] = ss[j + 1][j + i - 1]; /// И ответ для этой строки , это ответ для отрезка l+1, r-1
- if (isa(s[j], s[j + i])) /// однако , если наши боковые скобки валидны
- {
- ss[j][j + i] = "";/// то
- ss[j][j + i] += s[j] + ss[j + 1][j + i - 1];/// мы их и добовляем с дух сторон
- ss[j][j + i] += s[j + i];
- }
- /// Тем самым , после этого действися ,
- /*
- последоватенльности будут равны
- ( ) ==( )
- {( ) ==( )
- {( )]==( )
- а при [ { ( ) ] ] ответом будет === [ ( ) ]
- только при помощи этого дейстия
- -----
- тогда , исходя из всего того , что было выше
- мы будем знать для любого l и r самую большу правильную последовательность
- ( ) == ( )
- { ( ) = = ( )
- { ( ) X { ( ) == ( ) + ( ) && ( ) X { ( ) == ()+()
- { ( ) { ( ) } == ( ) { ( ) == "{"+( )+( )+"}"
- -
- */
- }
- }
- }
- fout << ss[0][n - 1];
- cin >> n;
- }
Add Comment
Please, Sign In to add comment