3295: 括号序列 -(序列DP)
描述
给定一串字符串,只由 “[”、“]” 、“(”、“)”四个字符构成。现在让你尽量少的添加括号,得到一个规则的序列。
例如:“()”、“[]”、“(())”、“([])”、“()[]”、“()[()]”,都是规则的序列。这几个不是规则的,如:“(”、“[”、“]”、“)(”、“([()”。
输入
输入有多组测试数据。输入一串字符串序列,长度不大于255。
输出
输出最少添加的括号数目。
样例输入
样例输出
题目来源
这个题是问需要添加多少个括号使之成为合 法括号序列,那么我们可以先求有多少合法 的括号匹配,然后用字符串长度减去匹配的 括号数就行 状态转移方程主要是对于我们枚举的区间 dp[i][j],如果i和j处的括号能够匹配,则 dp[i][j]=dp[i+1][j-1]+1; 因为我们是从小到大枚举长度,所以小长 度 的区间一定是最优的,所以当 i 与 j 匹配 时,则是子区间的最优值+1
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 3 */ 4 #include<iostream> 5 #include<cstring> 6 #include<cstdio> 7 #include<cmath> 8 using namespace std; 9 string s; 10 int f[500][500]; 11 int main() { 12 while(cin>>s){ 13 memset(f,0,sizeof f); 14 int n=s.size(); 15 for(int w=1;w<=n;w++) f[w][w]=1; 16 for(int l=2;l<=n;l++) 17 for(int i=1;i<=n-l+1;++i) 18 { 19 int j=l+i-1; 20 f[i][j]=2147483647; 21 if((s[i-1]=='('&&s[j-1]==')')||(s[i-1]=='['&&s[j-1]==']'))f[i][j]=f[i+1][j-1]; 22 for(int k=i;k<=j-1;k++) 23 f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]); 24 } 25 printf("%d\n",f[1][n]); 26 } 27 return 0; 28 }
作者:乌鸦坐飞机
出处:http://www.cnblogs.com/whistle13326/
新的风暴已经出现
怎么能够停止不前
穿越时空 竭尽全力
我会来到你身边
微笑面对危险
梦想成真不会遥远
鼓起勇气 坚定向前
奇迹一定会出现