括号序列

【题目描述】

定义合法的括号序列如下:

(1)空序列是一个合法的序列;

(2)如果S是合法的序列,则(S)和[S]也是合法的序列;

(3)如果A和B是合法的序列,则AB也是合法的序列;

下面的都是合法的括号序列:

()、[]、(())、([])、()[]、()[()];

下面的都是非法的括号序列:

(、[、)、)(、([)]、([(];

给定一个由(、)、[、]组成的序列,找出以该序列为子序列的最短合法序列。

【输入描述】

一行字符S(0 <= S <= 100)。

【输出描述】

一行字符,表示最短合法序列。

【样例输入】

([)]

【样例输出】

()[()]

源代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,f[101][101];
char S[101];
bool Match(char t1,char t2) //匹配判断。
{
    return (t1=='('&&t2==')')||(t1=='['&&t2==']');
}
void DP() //动态规划。
{
    for (int a=0;a<n;a++)
    {
        f[a+1][a]=0;
        f[a][a]=1;
    }
    for (int a=n-2;a>=0;a--) //从(n-2)才能将S分成两部分。
      for (int b=a+1;b<n;b++) //从当前节点到末尾。
      {
          f[a][b]=n; //符合实际的极大值。
          if (Match(S[a],S[b]))
            f[a][b]=min(f[a][b],f[a+1][b-1]); //Situation 1。
          for (int c=a;c<b;c++)
            f[a][b]=min(f[a][b],f[a][c]+f[c+1][b]); //Situation 2。
      }
}
void Print(int t1,int t2) //输出。
{
    if (t1>t2) //数据不符合实际。
      return;
    if (t1==t2) //数据为单个字符。
    {
        if (S[t1]=='('||S[t1]==')')
          printf("()");
        else
          printf("[]");
        return;
    }
    int ans=f[t1][t2];
    if (Match(S[t1],S[t2])&&ans==f[t1+1][t2-1]) //Situation 1。
    {
        printf("%c",S[t1]);
        Print(t1+1,t2-1); //递归搜索。
        printf("%c",S[t2]);
        return;
    }
    for (int a=t1;a<t2;a++) //Situation 2。
      if (ans==f[t1][a]+f[a+1][t2])
      {
          Print(t1,a);
          Print(a+1,t2);
          return;
      }
}
int main()
{
    gets(S); //可能含有空串,故scanf()不可行。
    n=strlen(S);
    DP();
    Print(0,n-1); //一步一步地穿越千山万水,回到起源的大地。
    printf("
"); //我的
不可能这么坑爹!
}

/*
    新奇的动归题目,输出也繁琐。
    设f[i][j]表示字符串S[i~j]至少需要添加的括号数,状态转移无非为以下两种情况:
        ①对应字符串S的f[]等于"[S]"或"(S)"对应的f[]。
        ②字符串S(S>=2)可划分为A、B两个子串,A、B所对应的f[]之和等于S对应的f[]。
    综上得状态转移方程:
        f[i][j]=min(f[i+1][j-1],f[i][k]+f[k+1][j](i<=k<j))。
    总结教训:
        看到一个题目最好先冷静分析一下,不必在意时间长短,脑子要灵活,不要觉得这道题好像用什么方法做就得用什么方法做。
*/
原文地址:https://www.cnblogs.com/Ackermann/p/5775716.html