zoukankan      html  css  js  c++  java
  • nyoj 15 括号匹配(2)

    括号匹配(二)

    时间限制:1000 ms  |  内存限制:65535 KB
    难度:6
    描述
    给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来。
    如:
    []是匹配的
    ([])[]是匹配的
    ((]是不匹配的
    ([)]是不匹配的
    输入
    第一行输入一个正整数N,表示测试数据组数(N<=10)
    每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度不超过100
    输出
    对于每组测试数据都输出一个正整数,表示最少需要添加的括号的数量。每组测试输出占一行
    样例输入
    4
    []
    ([])[]
    ((]
    ([)]
    样例输出
    0
    0
    3
    2
    分析题目:
    用 dp[j][i] 表示从位置 j 到字符位置 i 所需的最少括号数(i > j),那么这一状态可由下面得到:
    1.如果 第j个字符到第i - 1个字符中没有与第i个字符匹配的括号,则所需的括号数加1,
            即:f[j][i] = f[j][i - 1] + 1;
    2.如果 k=j 时正好匹配则  因为dp[j][j-1]=0,这就是第一次匹配(注意可能存在多个字符与之匹配,即可能存在多个k) ;                 
            即:dp[j][i]=min(dp[j][i],dp[k+1][i-1]);
    3.如果 第k(j < k < i)个字符再次与第i个字符匹配,那么所需括号数为第j到第k - 1个字符所需字符数加上第k + 1个字符到第i - 1个字符  ,所需括号数为
            即:dp[j][i] = min(dp[j][i], dp[j][k - 1] + dp[k + 1][i - 1])。
      例如:这种情况 [ ) ) [ ( ( [ ) ) ] 当 i 为 len-1 时
                  1     2     3        1为第一次匹配,2为第二次匹配。。。
    AC代码一:
     1 //第二种情况,和第三种合并为了一种,因为dp[j][j-1]=0;
     2 #include<cstdio>
     3 #include<iostream>
     4 #include<cstring>
     5 using namespace std;
     6 bool f(char a,char b)
     7 {
     8     if(a=='('&&b==')')
     9         return 1;
    10     if(a=='['&&b==']')
    11         return 1;
    12     return 0;
    13 }
    14 int dp[200][200];
    15 int main()
    16 {
    17     int n ;
    18     cin>>n;
    19     while(n--)
    20     {
    21         string s;
    22         cin >> s;
    23         int len = s.length();
    24         memset(dp,0,sizeof(dp));
    25         for(int i = 0 ; i <= len ; i++)
    26             dp[i][i]=1;
    27         for(int i = 1 ; i < len ; i++){
    28             for(int j = i-1 ; j >= 0; j--)
    29             {
    30                 dp[j][i] = dp[j][i-1] + 1;
    31                 for(int k = j ; k < i ; ++ k)
    32                 {
    33                     if(f(s[k],s[i]))//当k=j时,为第一次与s[i]匹配;
    34                     {
    35                         dp[j][i]=min(dp[j][i],dp[j][k-1]+dp[k+1][i-1]);
    36                     }
    37                 }
    38             }
    39         }
    40         printf("%d
    ",dp[0][len-1]);
    41     }
    42     return 0;
    43 }
    View Code

      AC代码二:

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<string.h>
     4 #include<iostream>
     5 using namespace std;
     6 #define N 101
     7 #define MAX 0xfffffff
     8 int dp[N][N];
     9 int min(int a,int b)
    10 {
    11 return a<b ? a:b;
    12 }
    13 int main()
    14 {
    15 int t,len,i,j,l,k,mmin,s;
    16 char a[N];
    17 scanf("%d",&t);
    18 while(t--)
    19     {
    20          cin>>a;
    21          len = strlen(a);
    22     memset(dp,0,sizeof(dp));
    23     for(i=0;i<len;i++)
    24     dp[i][i]=1;                                              //一个括号需要加一个括号才能被匹配成功
    25     for(i=1;i<len;i++)
    26        for(j=0;j<len-i;j++)
    27         {
    28             k=j+i;  mmin=MAX;
    29              dp[j][k]=MAX;
    30         if( ( a[j]=='(' && a[k]==')' ) || ( a[j]=='['&&a[k]==']' ) )  //如果匹配,则无需添加括号
    31               dp[j][k]=dp[j+1][k-1];
    32                                                             //局部最小
    33         for(l=j;l<=k;l++)                                       //如果不需要,就找到添加的位置
    34           {
    35              mmin = min(mmin,dp[j][l]+dp[l+1][k]);
    36           }
    37                                                             //整体最小
    38               dp[j][k]=min(dp[j][k],mmin);
    39          }
    40               printf("%d
    ",dp[0][len-1]);
    41   }
    42 return 0;
    43 }
    View Code
  • 相关阅读:
    linux查看系统类型和版本
    javascript 中的继承实现, call,apply,prototype,构造函数
    redis原理分析
    HashTable 简述
    算法之 快速排序
    react js 之生命周期
    Java源代码编译过程
    Java字节码文件结构---概述
    Java程序运行时内存划分
    数据结构--汉诺塔--借助栈实现非递归---Java
  • 原文地址:https://www.cnblogs.com/lovychen/p/3652743.html
Copyright © 2011-2022 走看看