NYOJ_15_括号匹配(二)【区间DP】

来源:互联网 发布:淘宝互刷收藏qq群 编辑:程序博客网 时间:2024/05/16 14:27
/*
括号匹配(二)
时间限制:1000 ms  |  内存限制:65535 KB
难度:6

描述
    给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来。
    如:
    []是匹配的
    ([])[]是匹配的
    ((]是不匹配的
    ([)]是不匹配的

输入
    第一行输入一个正整数N,表示测试数据组数(N<=10)
    每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度不超过100
输出
    对于每组测试数据都输出一个正整数,表示最少需要添加的括号的数量。每组测试输出占一行
样例输入

4
[]
([])[]
((]
([)]

样例输出

    0
    0
    3
    2
    
区间dp,二维数组储存需要添加的括号的个数,dp[i][j]表示从第i位到第j位区间需要添加的括号数,
当i==j时,dp[i][i]所选区间只有一个括号,所以dp[i][i]=1;


例如: CC] 长度为 3
      需要在(0,2)的区间找值
     (0,2)可以分成(0,1),(2,2) 或者  (0,0),(1,2)  两者中取最小
    
      
     (0,2)  中的(0,1)  分为 (0,0)(1,1)的子区间      (2,2)
     (0,2)  中的(1,2)  分为 (1,1)(2,2)的区间      (0,0)   两者取最小
    
     dp[i][j]
    
       0   1    2
    0   1   2    3
    1   0   1    2
    2   0   0    1  

*/

#include <cstdio>  #include <cstring> #include <algorithm> using namespace std; const int MAX =  101;  int dp[MAX][MAX];  char s[101];int main()  {      int n,i,j,k,width;      scanf("%d",&n);      while(n--)      {          scanf("%s",s);          int length = strlen(s);          memset(dp,0,sizeof(dp));          for(i = 0; i < length; i++)  {              dp[i][i] = 1;   //只有一个字符,匹配一个字符        }          for(width = 1; width < length; width++)   // 区间长度         {              for(i = 0; i < length - width; i++)  //区间开始位置             {                  j = i + width;    //区间结束位置                 dp[i][j] = MAX;                   if((s[i] == '(' && s[j] == ')') || (s[i] == '[' && s[j] == ']'))//在该区间中找到配对的两个 ,左右区间都缩小一下,在给值前值比较                 dp[i][j] = min(dp[i][j],dp[i+1][j-1]);                  for(k = i; k < j; k++)  {          //划分成更小的区间找值                    dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]);                  }              }          }          printf("%d\n",dp[0][length-1]);      }      return 0;  }     


0 0
原创粉丝点击