最長括號匹配_NOI導刊2009提高 字串dp
阿新 • • 發佈:2019-02-14
題目描述
對一個由(,),[,]括號組成的字串,求出其中最長的括號匹配子串。具體來說,滿足如下條件的字串成為括號匹配的字串:
1.(),[]是括號匹配的字串。
2.若A是括號匹配的串,則(A),[A]是括號匹配的字串。
3.若A,B是括號匹配的字串,則AB也是括號匹配的字串。
例如:(),[],([]),()()都是括號匹配的字串,而](則不是。
字串A的子串是指由A中連續若干個字元組成的字串。
例如,A,B,C,ABC,CAB,ABCABCd都是ABCABC的子串。空串是任何字串的子串。
輸入輸出格式
輸入格式:
輸入一行,為一個僅由()[]組成的非空字串。
輸出格式:
輸出也僅有一行,為最長的括號匹配子串。若有相同長度的子串,輸出位置靠前的子串。
輸入輸出樣例
輸入樣例#1: 複製
([(][()]]()
輸出樣例#1: 複製
[()]
輸入樣例#2: 複製
())[]
輸出樣例#2: 複製
()
考慮 dp [ i ] 表示 以 i 位置開始的字串能匹配的最長長度,
自然從後往前遍歷;
那麼考慮題目中的條件;
有兩個轉移方程:
** dp[ i ] = dp[ i-1 ]+2 **
dp[ i ]+=dp[ i+dp[ i ] ]
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include <cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
#include<cctype>
//#pragma GCC optimize("O3")
using namespace std;
#define maxn 200005
#define inf 0x3f3f3f3f
#define INF 0x7fffffff
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const long long int mod = 1e9 + 7;
#define Mod 20100403
#define sq(x) (x)*(x)
#define eps 1e-15
const int N = 2500005;
inline int rd() {
int x = 0;
char c = getchar();
bool f = false;
while (!isdigit(c)) {
if (c == '-') f = true;
c = getchar();
}
while (isdigit(c)) {
x = (x << 1) + (x << 3) + (c ^ 48);
c = getchar();
}
return f ? -x : x;
}
ll gcd(ll a, ll b) {
return b == 0 ? a : gcd(b, a%b);
}
string dat;
int dp[maxn << 3];
int main()
{
ios::sync_with_stdio(false);
cin >> dat;
int id = 0;
for (int i = dat.length()-1; i >= 0; i--) {
if (dat[i] == ')' || dat[i] == ']')continue;
if ((dat[i + dp[i + 1] + 1] == ')'&&dat[i] == '(') || (dat[i + dp[i + 1] + 1] == ']'&&dat[i] == '[')) {
dp[i] = dp[i + 1] + 2;
dp[i] += dp[i + dp[i]];
if (dp[i] >= dp[id]) {
id = i;
}
}
}
for (int i = 0; i < dp[id]; i++) {
cout << dat[id + i];
}
cout << endl;
return 0;
}