• 括号序列


    题目描述

      定义如下规则序列(字符串):

        1.空序列是规则序列;

        2.如果S是规则序列,那么(S)和[S]也是规则序列;

        3.如果A和B都是规则序列,那么AB也是规则序列。

      例如,下面的字符串都是规则序列:

        (),[],(()),([]),()[],()[()]

      而以下几个则不是:

        (,[,],)(,()),([()

      现在,给你一些由‘(’,‘)’,‘[’,‘]’构成的序列,你要做的,是找出一个最短规则序列,使得给你的那个序列是你给出的规则序列的子列。(对于序列a1,a2,…,an和序列bl,b2,…,bm,如果存在一组下标1≤i1<i2<…<in≤m,使得aj=b(i,j)对一切1≤j≤n成立,那么a1,a2…,an就叫做b1,b2,…,bm的子列。

    输入输出格式

      输入格式:

        输入文件仅一行,全部由‘(’,‘)’,‘]’,‘]’组成,没有其他字符,长度不超过100。

      输出格式:

        输出文件也仅有一行,全部由‘(’,‘)’,‘]’,‘]’组成,没有其他字符,把你找到的规则序列输出即可。因为规则序列可能不止一个,因此要求输出的规则序列中嵌套的层数尽可能地少。

    输入输出样例

      输入样例#1:
      ([()
    
      输出样例#1:
      ()[]()
    

    说明

      输出解释:

      {最多的嵌套层数为1,如层数为2时的一种为()[()]}

    jsoi2011

    【题目分析】

        说一下大体思路,dp[i][j]表示从i到j需要插入的括号的个数,path[i][j]记录i到j中划分位置k,递归输出

        非满分算法

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    const int maxn=1100;
    char str[maxn];
    int dp[maxn][maxn],p[maxn][maxn],len;
    void print(int start,int end)
    {
        if(start>end)
            return ;
        else if(start==end)//找到没有被匹配的括号 
        {
            if(str[start]=='('||str[end]==')')
                printf("()");
            else 
                printf("[]");
        }
        else if(p[start][end]==-1)//如果这段括号中没有被分割的位置 
        {
            printf("%c",str[start]);
            print(start+1,end-1);
            printf("%c",str[end]);
        }
        else //从p[start][end]处被分开,递归输出 
        {
            print(start,p[start][end]);
            print(p[start][end]+1,end);
        }
    }
    int main()
    {
        memset(dp,0,sizeof dp);
        scanf("%s",str+1);
        len=strlen(str+1);
        for(int i=1;i<=len;i++)
            dp[i][i]=1;
        for(int l=2;l<=len;l++)
            for(int i=1;i<=len-1;i++)
            {
                int j=i+l-1;
                if(str[i]=='('&&str[j]==')'||str[i]=='['&&str[j]==']')
                    dp[i][j]=dp[i+1][j-1],
                    p[i][j]=-1;
                else dp[i][j]=0x7fffffff;
                for(int k=i;k<=j-1;k++)
                  if(dp[i][j]>dp[i][k]+dp[k][j])
                    dp[i][j]=dp[i][k]+dp[k][j],
                    p[i][j]=k;
            }
        print(1,len);
        return 0;
    }
  • 相关阅读:
    mysql 8.x 忘记密码
    sqlite
    公租房查询记录
    idea 常用快捷键总结
    vue h5项目中上传图片时保存之后显示不全
    微信小程序开发中使用npm命令快速添加页面
    【Luogu7816】「Stoi2032」以父之名
    【XSY3657】 因数分解
    Min_25筛学习笔记
    拉格朗日反演学习笔记
  • 原文地址:https://www.cnblogs.com/xiaoningmeng/p/5878911.html
Copyright © 2020-2023  润新知