Brackets Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6622 Accepted: 3558 Description We give the following inductive definition of a “r ...
Brackets
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 6622 | Accepted: 3558 |
Description
We give the following inductive definition of a “regular brackets” sequence:
- the empty sequence is a regular brackets sequence,
- if s is a regular brackets sequence, then (s) and [s] are regular brackets sequences, and
- if a and b are regular brackets sequences, then ab is a regular brackets sequence.
- no other sequence is a regular brackets sequence
For instance, all of the following character sequences are regular brackets sequences:
(), [], (()), ()[], ()[()]
while the following character sequences are not:
(, ], )(, ([)], ([(]
Given a brackets sequence of characters a1a2 … an, your goal is to find the length of the longest regular brackets sequence that is a subsequence of s. That is, you wish to find the largest m such that for indices i1, i2, …, im where 1 ≤ i1 < i2 < … < im ≤ n, ai1ai2 … aim is a regular brackets sequence.
Given the initial sequence ([([]])]
, the longest regular brackets subsequence is [([])]
.
Input
The input test file will contain multiple test cases. Each input test case consists of a single line containing only the characters (
, )
, [
, and ]
; each input test will have length between 1 and 100, inclusive. The end-of-file is marked by a line containing the word “end” and should not be processed.
Output
For each input case, the program should print the length of the longest possible regular brackets subsequence on a single line.
Sample Input
((()))
()()()
([]])
)[)(
([][][)
end
Sample Output
6
6
4
0
6
Source
Stanford Local 2004 題目大意:給你一個長度不超過100的括弧序列,求最長合法括弧子序列的長度。合法的括弧序列滿足下列條件: 1.空的括弧序列是合法的; 2.如果一個括弧序列s是合法的,那麼(s)和[s]都是合法的; 3.如果兩個括弧序列a和b都是合法的,那麼ab也是合法的; 4.其他的括弧序列都是不合法的。 例如:(), [], (()), ()[], ()[()]都是合法的,而(, ], )(, ([)], ([(]都是不合法的。 解題思路:一道典型的區間DP模型題目。分析一下問題,可以發現:如果找到一對匹配的括弧,例如[xxx]oooo,就把區間分成兩部分,一部分是xxx,另一部分是oooo。 設dp[i][j]表示區間[i,j]之間的最長合法括弧子序列的長度,那麼當i<j時,如果區間[i+1,j]內沒有與i匹配的括弧,則dp[i][j]=dp[i+1][j];如果存在一個與之匹配的k,那麼dp[i][j]=max{dp[i+1][j], dp[i+1][k-1]+dp[k+1][j]+1(i<=k<=j&&i和k是一對匹配的括弧)}。因此,我們將整個串長作為區間進行搜索,那麼最後2*dp[0][len-1]即為答案,len表示串的長度。詳見代碼。 附上AC代碼:1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 const int maxn = 105; 5 char str[maxn]; 6 int dp[maxn][maxn]; 7 8 bool match(char a, char b){ 9 return (a=='('&&b==')') || (a=='['&&b==']'); 10 } 11 12 int dfs(int l, int r){ 13 if (l >= r) 14 return 0; 15 if (l+1 == r) 16 return dp[l][r] = match(str[l], str[r]); 17 if (dp[l][r]) 18 return dp[l][r]; 19 int ans = dfs(l+1, r); 20 for (int i=l; i<=r; ++i) 21 if (match(str[l], str[i])){ 22 int t = dfs(l+1, i-1)+dfs(i+1, r)+1; 23 if (t > ans) 24 ans = t; 25 } 26 return dp[l][r] = ans; 27 } 28 29 int main(){ 30 while (~scanf("%s", str) && str[0]!='e'){ 31 memset(dp, 0, sizeof(dp)); 32 int len = strlen(str); 33 dfs(0, len-1); 34 printf("%d\n", 2*dp[0][len-1]); 35 } 36 return 0; 37 }View Code