括号匹配(二)
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
6
-
描述
-
给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来。
如:
[]是匹配的
([])[]是匹配的
((]是不匹配的
([)]是不匹配的-
输入
-
第一行输入一个正整数N,表示测试数据组数(N<=10)
每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度不超过100
输出
- 对于每组测试数据都输出一个正整数,表示最少需要添加的括号的数量。每组测试输出占一行 样例输入
-
4 [] ([])[] ((] ([)]
样例输出
-
0 0 3 2
/* 区间dp,加油!!! Time:2015-4-18 10:44 */ #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int INF=0x3f3f3f3f; const int MAX=100+10; char str[MAX]; int dp[MAX][MAX]; bool f[MAX][MAX]; bool match(int i,int j){//注意:判断条件不能用str[i]==str[j],因为会出现都等于0 的情况 if(str[i]=='('&&str[j]==')'||str[i]=='['&&str[j]==']') return true; return false; } int main(){ int T; scanf("%d",&T); while(T--){ scanf("%s",str+1); int len=strlen(str+1); memset(dp,0,sizeof(dp)); memset(f,0,sizeof(f)); for(int i=0;i<=len;i++) dp[i][i]=1; for(int i=1;i<=len;i++){ for(int j=i-1;j>=1;j--){ bool flag=false; for(int k=j;k<=i-1;k++){ if(match(k,i)){ if(f[j][i])dp[j][i]=min(dp[j][i],dp[j][k-1]+dp[k+1][i-1]); else{ f[j][i]=1; dp[j][i]=dp[j][k-1]+dp[k+1][i-1]; } flag=true; } } if(!flag)dp[j][i]=dp[j][i-1]+1; } } printf("%d\n",dp[1][len]); } return 0; }
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int INF=0x3f3f3f3f; const int MAX=100+10; char str[MAX]; int dp[MAX][MAX]; bool match(int i,int j){//注意:判断条件不能用str[i]==str[j],因为会出现都等于0 的情况 if(str[i]=='('&&str[j]==')'||str[i]=='['&&str[j]==']') return true; return false; } int main(){ int T; scanf("%d",&T); while(T--){ scanf("%s",str); int len=strlen(str); memset(dp,0,sizeof(dp)); for(int i=0;i<=len;i++) dp[i][i]=1; for(int c=1;c<len;c++){ for(int i=0;i<len-c;i++){ int j=i+c; dp[i][j]=INF; if(match(i,j)) dp[i][j]=min(dp[i][j],dp[i+1][j-1]); for(int k=i;k<=j;k++){ dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]); } } } printf("%d\n",dp[0][len-1]); } return 0; }
-
第一行输入一个正整数N,表示测试数据组数(N<=10)