标签:
Time Limit: 1000MS | Memory Limit: 65536K | |||
Total Submissions: 29502 | Accepted: 8402 | Special Judge |
Description
Input
Output
Sample Input
([(]
Sample Output
()[()]
Source
题目大意: 给你一贯括号序列(只包含小括号和中括号),让你找出长度最小的regular brackets sequence包含此子序列.其中的regular brackets sequence定义如下:
1)空序列是一个regular brackets sequence;
2)如果s是一个regular brackets sequence,那么[s] 也是一个regular brackets sequence,(s)也是一个regular brackets sequence.
3)如果A,B都是regular brackets sequence,那么AB也是一个regular brackets sequence.
例如:()、[]、()[] 、([]) 、([])()[()]都是regular brackets sequence。
而[[[、 (((((、 ([)] 则都不是regular brackets sequence。其中以“([)]”为例,包含它最小的regular brackets sequence有两个:()[()]或者是([])[].而你只要输出其中一个就行。
#include<iostream> #include<cstdio> #include<cstring> #define N 105 #define INF 0x3f3f3f3f using namespace std; char s[N]; int f[N][N],path[N][N]; /*f[i][j]表示区间i~j内需要最少的字符数能够匹配,path[i][j]表示到达该状态是哪种情况, -1表示第一个和最后一个,其他表示中间的分段点,然后递归输出 递归改变次序 */ void out(int l,int r){ if(l>r) return ; if(l==r){//到达了最后 if(s[l]==‘(‘||s[l]==‘)‘) printf("()"); else printf("[]"); return ; } if(path[l][r]==-1){//首尾,先输出开始,然后递归输出中间,最后输出结尾 putchar(s[l]); out(l+1,r-1); putchar(s[r]); } else{ out(l,path[l][r]); out(path[l][r]+1,r); } } int main() { while(gets(s+1)){//有空串,scanf("%s"),不能读空串,然后少一个回车,会出错 int n=strlen(s+1); memset(f,0,sizeof(f)); for(int i=1;i<=n;i++) f[i][i]=1;//一个的话只需一个就可以匹配 for(int x=1;x<n;x++) //枚举区间长度 for(int i=1;i<=n-x;i++){ //枚举区间开始位置 int j=i+x; f[i][j]=INF; if((s[i]==‘[‘&&s[j]==‘]‘)||(s[i]==‘(‘&&s[j]==‘)‘)) //首尾情况 if(f[i+1][j-1]<f[i][j]) f[i][j]=f[i+1][j-1],path[i][j]=-1; for(int k=i;k<j;k++) //中间分隔情况 if(f[i][k]+f[k+1][j]<f[i][j]) f[i][j]=f[i][k]+f[k+1][j],path[i][j]=k; } out(1,n); putchar(‘\n‘); } return 0; }
标签:
原文地址:http://www.cnblogs.com/shenben/p/5495730.html