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("
");
//		}
//		cout << endl;
		printf("%d
", d[0][n-1]);
	}
	return 0;
}




原文地址:https://www.cnblogs.com/lzq1126/p/5596858.html