括号序列

问题 C: 括号序列

时间限制: 1 Sec  内存限制: 128 MB
提交: 109  解决: 56
[提交][状态][讨论版]

题目描述

定义如下规则序列(字符串): 
1.空序列是规则序列; 
2.如果S是规则序列,那(S)和[S]也是规则序列; 
3.如果A和B都是规则序列,那么AB也是规则序列。 
例如,下面的字符串都是规则序列: 
(), [], (()), ([]), ()[], ()[()] 
这几个不是规则序列: 
(, [, ], )(, ([() 
现在,给出一些有'(' , ')' , '[' , ']'组成的序列,请添加尽量少的括号,得到一个规则序列,并输出该序列的长度。

 

输入

输入一个有'(' , ')' , '[' , ']'组成的序列,长度不超过200

 

输出

输出规则后的字串长度

 

样例输入

([(]

样例输出

6

提示

 ([()])//6

这题也是一道分段类DP,如果l,r两个边界刚好为一对,及为()或[],这样的话则dp[l][r]=dp[l+1][r-1]。

然后再枚举中间点,记忆化,或者for循环形式都是可以的,我个人的话练了练for的形式,记忆化比较好理解。

#include<cstdio> 
#include<algorithm> 
#include<iostream> 
#include<cmath> 
#include<cstring> 
#include<string> 
using namespace std; 
  
const int MAXN=207; 
char s[MAXN]; 
int dp[MAXN][MAXN]; 
  
bool match(char c1,char c2) 
{ 
    if ((c1=='('&&c2==')')||(c1=='['&&c2==']')) return true; 
    return false; 
      
} 
int main() 
{ 
    scanf("%s",s); 
    int len=strlen(s); 
    int n=len; 
    memset(dp,0,sizeof(dp)); 
    for (int i=1;i<=len;i++) 
        dp[i][i]=1; 
    for (int i=1;i<len;i++) 
        if (match(s[i-1],s[i])) dp[i][i+1]=0; 
        else dp[i][i+1]=2; 
    for (int t=2;t<=n-1;t++) 
        for (int i=1;i<=n-t;i++) 
        { 
            if (match(s[i-1],s[i+t-1])) dp[i][i+t]=dp[i+1][i+t-1]; 
            else dp[i][i+t]=MAXN*MAXN*MAXN; 
            for (int j=0;j<=t-1;j++) 
                dp[i][i+t]=min(dp[i][i+t],dp[i][i+j]+dp[i+j+1][i+t]); 
        } 
    printf("%d",dp[1][len]+len);     
} 

 

posted @ 2017-05-22 18:20  Kaiser-  阅读(265)  评论(0编辑  收藏  举报