标签:
题目链接 http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=15
给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来。
如:
[]是匹配的
([])[]是匹配的
((]是不匹配的
([)]是不匹配的
分析:要求要添加多少个,可以求出最大匹配的长度,这样剩下的都是没有匹配的,所以每个对于一个匹配就可以了。
即 答案 = 字符串长度 - 最大匹配长度。
首先考虑怎么样定义dp让它满足具有通过子结构来求解、
定义dp [ i ] [ j ] 为串中第 i 个到第 j 个括号的最大匹配数目
那么我们假如知道了 i 到 j 区间的最大匹配,那么i+1到 j+1区间的是不是就可以很简单的得到。
那么 假如第 i 个和第 j 个是一对匹配的括号那么dp [ i ] [ j ] = dp [ i+1 ] [ j-1 ] + 2 ;
那么我们只需要从小到大枚举所有 i 和 j 中间的括号数目,然后满足匹配就用上面式子dp,然后每次更新dp [ i ] [ j ]为最大值即可。
更新最大值的方法是枚举 i 和 j 的中间值,然后让 dp[ i ] [ j ] = max ( dp [ i ] [ j ] , dp [ i ] [ f ] + dp [ f+1 ] [ j ] ) ;
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <string> 5 #include <algorithm> 6 using namespace std; 7 #define maxn 110 8 int N, dp[maxn][maxn]; 9 string s; 10 int main(){ 11 scanf("%d", &N); 12 13 while(N--){ 14 memset(dp, 0, sizeof(dp)); 15 cin>>s; 16 for(int len = 1; len < s.size(); len++){ 17 for(int i = 0, j = len; j < s.size(); i++,j++){ 18 if(s[i] == ‘(‘ && s[j] == ‘)‘ || s[i] == ‘[‘ && s[j] == ‘]‘) 19 dp[i][j] = dp[i+1][j-1] + 2; 20 for(int k = i; k < j; k++) 21 dp[i][j] = max(dp[i][j] , dp[i][k] + dp[k][j]); 22 } 23 } 24 printf("%d\n", s.size()-dp[0][s.size()-1]); 25 26 } 27 28 return 0; 29 }
类似题 POJ 2955 http://poj.org/problem?id=2955
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <string> 5 #include <algorithm> 6 using namespace std; 7 #define maxn 110 8 int N, dp[maxn][maxn]; 9 string s; 10 int main(){ 11 while(cin>>s){ 12 if(s == "end") break; 13 memset(dp, 0, sizeof(dp)); 14 15 for(int len = 1; len < s.size(); len++){ 16 for(int i = 0, j = len; j < s.size(); i++,j++){ 17 if(s[i] == ‘(‘ && s[j] == ‘)‘ || s[i] == ‘[‘ && s[j] == ‘]‘) 18 dp[i][j] = dp[i+1][j-1] + 2; 19 for(int k = i; k < j; k++) 20 dp[i][j] = max(dp[i][j] , dp[i][k] + dp[k][j]); 21 } 22 } 23 printf("%d\n", dp[0][s.size()-1]); 24 25 } 26 27 return 0; 28 }
标签:
原文地址:http://www.cnblogs.com/titicia/p/4345018.html