nyoj15括号匹配(二)
括号匹配(二)
时间限制:1000 ms | 内存限制:65535 KB
难度:6
- 描述
- 给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来。
如:
[]是匹配的
([])[]是匹配的
((]是不匹配的
([)]是不匹配的- 输入
- 第一行输入一个正整数N,表示测试数据组数(N<=10)
每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度不超过100 - 输出
- 对于每组测试数据都输出一个正整数,表示最少需要添加的括号的数量。每组测试输出占一行
- 样例输入
-
4 [] ([])[] ((] ([)]
- 样例输出
-
0 0 3 2
分析: 设串S至少需要增加d(S)括号,转移如下:
1.如果s形如(S‘)或者[S'],转移到d(S')。
2.如果S至少有两个字符,则可分成AB,转移到d(A)+d(B).
边界是:S为空串是d(S) = 0, S为单字符串是d(S)=1。注意(S' , [S' , )S'之类全部属于第二种转移,不需要单独处理。
不管S是否满足第一条,都要尝试第二种转移,否则“[][]”会转移到"][",然后就只能加两个括号了。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; int d[102][102], n; char s[110]; int match(char a, char b) //括号匹配函数 { return ((a == '(' && b == ')' )|| (a == '[' && b == ']')); } void dp() { int i, j, k; for(i = 0; i < n; i++) { d[i][i] = 1; d[i+1][i] = 0; } for(i = n-2; i >=0; i--) { for(j = i+1; j < n; j++) { d[i][j] = n; if(match(s[i],s[j])) d[i][j] = min(d[i][j], d[i+1][j-1]); //状态1转移 for(k = i; k < j; k++) { d[i][j] = min(d[i][j], d[i][k] + d[k+1][j]); //无论是否有状态1,全部转移状态2 } } } } int main() { //freopen("in.txt", "r", stdin); int t; scanf("%d", &t); getchar(); while(t--) { memset(d, 0, sizeof(d)); gets(s); n = strlen(s); dp(); // for(int i = 0 ; i < n; i++) // { // for(int j = 0; j < n; j++) // { // printf("%d", d[i][j]); // } // printf("\n"); // } // cout << endl; printf("%d\n", d[0][n-1]); } return 0; }