zoukankan      html  css  js  c++  java
  • POJ 1411:Brackets Sequence 区间DP

    Brackets Sequence

    题目链接:

    http://poj.org/problem?id=1141

    题意:

    给出一个只由'('、')'、'['、']'构成的字符串,字符间可以匹配,左边的 '(' 可以与右边的 ')' 匹配,左边的 '[' 可以与右边的 ']' 匹配

    两种匹配不能交叉,可以包含,如 [(])只算2个匹配而[()]算四个匹配,求最少加上几个字符可以使原串所有的字符都匹配,输出匹配后的字符串。

    题解:

    设dp[i][j]为将区间[i,j]补全的最小步数,to[i][j]为dp[i][j]取最小值时与 j 匹配的点,可以知道

        当区间[i,j-1]内没有可以与 j 匹配的点时,dp[i][j]=dp[i][j-1]+1,to[i][j]=j (j与自己匹配,额外加点)

        当区间[i,j-1]内有点k可以与j匹配时,dp[i][j]=dp[i][k-1]+dp[k+1][j-1],to[i][j]=k

    然后深搜找路径,将与自己匹配的点补全就行了,注意题目会有直接输入回车要输出回车的情况。

                  

    代码

    #include<stdio.h>
    #include<string.h>
    const int N=101;
    char s[N];
    bool ans[N];
    int dp[N][N],to[N][N];
    int mmin(int x,int y)
    {
      return x<y?x:y;
    }
    char Get_c(char c)
    {
      if(c==')')return '(';
      if(c=='(')return ')';
      if(c=='[')return ']';
      if(c==']')return '[';
    }
    void Dfs(int x,int y)
    {
      if(x>y)return;
      if(to[x][y]==y)
      {
        ans[y]=true;
        Dfs(x,y-1);
        return ;
      }
      if(to[x][y]==x)
      {
        Dfs(x+1,y-1);
        return ;
      }
      Dfs(x,to[x][y]-1);
      Dfs(to[x][y]+1,y-1);
    }
    void solve()
    {
      memset(dp,0,sizeof(dp));
      while(gets(s+1))
      {
        s[0]='?';
        int t=strlen(s)-1;
        for(int i=1;i<=t;++i)
        {
          dp[i][i]=1;
          to[i][i]=i;
          ans[i]=false;
        }
        for(int len=1;len<t;++len)
        {
          for(int i=1;i+len<=t;++i)
          {
            int j=i+len;
            char c=Get_c(s[j]);
            dp[i][j]=dp[i][j-1]+1;
            to[i][j]=j;
            if(c==']'||c==')')continue;
            for(int k=i;k<j;++k)
            if(s[k]==c&&dp[i][k-1]+dp[k+1][j-1]<dp[i][j])
            {
              dp[i][j]=dp[i][k-1]+dp[k+1][j-1];
              to[i][j]=k;
            }
          }
        }
        Dfs(1,t);
        for(int i=1;i<=t;++i)
        if(!ans[i])printf("%c",s[i]);
        else
        {
          if(s[i]=='('||s[i]=='[')printf("%c%c",s[i],Get_c(s[i]));
          else printf("%c%c",Get_c(s[i]),s[i]);
        }
        printf(" ");
      }
    }
    int main()
    {
      solve();
      return 0;
    }

  • 相关阅读:
    Qt MFC 混合编程的问题
    DECLARE_MESSAGE_MAP用法
    DECLARE_DYNCREATE与DECLARE_DYNAMIC区别
    Qt unsigned char* (uchar*) 转为QImage
    C++ SafeArrayAccessData,SafeArrayUnaccessData使用
    C++ 实现 COM → IUnknown → 接口
    C++ COM编程之IUnknown接口
    C++ COM三大接口:IUnknown、IClassFactory、IDispatch。
    C++ COM组件QueryInterface函数
    C++ COM组件的AddRef和Release()方法使用
  • 原文地址:https://www.cnblogs.com/kiuhghcsc/p/5749504.html
Copyright © 2011-2022 走看看