[ACM] 携程预赛第一场 括号匹配 (动态规划)
括号匹配
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 110 Accepted Submission(s) : 46
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
描述 给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来。
如:
[]是匹配的
([])[]是匹配的
((]是不匹配的
([)]是不匹配的
如:
[]是匹配的
([])[]是匹配的
((]是不匹配的
([)]是不匹配的
Input
第一行输入一个正整数N,表示测试数据组数(N<=100)。
每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度不超过100。
每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度不超过100。
Output
对于每组测试数据都输出一个正整数,表示最少需要添加的括号的数量。每组测试输出占一行。
Sample Input
4 [] ([])[] ((] ([)]
Sample Output
0 0 3 2
Source
CodingTrip - 携程编程大赛 (预赛第一场)
代码:
#include <iostream> #include <algorithm> #include <stdio.h> #include <string.h> #include <stdlib.h> using namespace std; const int maxn=250; const int inf=0x7fffffff; char str[maxn]; int dp[maxn][maxn],ps[maxn][maxn]; //dp[i][j]代表串从i到j需要添加几个字符才能合法,ps[i][j],记录的从i到j在哪里断成两部分 int len; int main() { int k;cin>>k; while(k--) { cin>>str; len=strlen(str); memset(dp,0,sizeof(dp)); for(int i=0;i<len;i++) dp[i][i]=1; for(int k=1;k<len;k++)//区间从小到大 for(int i=0;i+k<len;i++) { int j=i+k; dp[i][j]=inf; if((str[i]=='('&&str[j]==')')||(str[i]=='['&&str[j]==']')) { dp[i][j]=dp[i+1][j-1]; ps[i][j]=-1;//括号匹配,不用添加另外的括号 } for(int mid=i;mid<j;mid++)//看是否能划分为两部分 { if(dp[i][j]>(dp[i][mid]+dp[mid+1][j])) { dp[i][j]=dp[i][mid]+dp[mid+1][j]; ps[i][j]=mid;//mid为串i到j区间断开的位置 } } } cout<<dp[0][len-1]<<endl; } return 0; }