D - 选做题 - 1
- 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,
- andif 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
题目解析
- 采用区间dp的算法思想
- 定状态为dp[i][j]表示i-j最少需要添加的括号数
- 转移方程
if a[i] match a[j]:
dp[i][j] = dp[i-1][j-1]
else :
dp[i][j] = min{dp[i][k]+dp[k+1][j]}
完整代码
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
string s;
int dp[110][110];
int num;
map<char, int> ch;
int main()
{
ch.insert(make_pair('(', 1));
ch.insert(make_pair(')', 2));
ch.insert(make_pair('[', 4));
ch.insert(make_pair(']', 5));
while (true)
{
cin >> s;
if (s == "end")
break;
num = s.size();
int ans = 0;
for (int i = 0; i < num; i++)
for (int j = 0; j < num; j++)
dp[i][j] = 0;
for (int lenth = 2; lenth <= num; lenth++)
for (int i = 0; i < num - lenth + 1; i++)
{
int j = i + lenth - 1;
if (ch.find(s.at(i))->second - ch.find(s.at(j))->second == -1)
dp[i][j] = dp[i + 1][j - 1] + 2;
for (int k = i; k < j; k++)
dp[i][j] = max(dp[i][j], dp[i][k] + dp[k + 1][j]);
ans = max(ans, dp[i][j]);
}
cout << ans << endl;
}
return 0;
}