南阳理工ACM 括号匹配问题,并求出使得括号能够匹配需要新增的最小括号数(括号匹配(二))

描述

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

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

解题思路

        如果仅仅是一般的判断括号是否匹配,直接扫描一遍数组,利用一个栈就可以判定YES还是OR。现在需要求解其输出的个数。可以联想到我们求解矩阵连乘问题,求解何种组合使得计算量最小。利用动态规划的方式求解。

        利用公式:M[i,j]=M[i,k]+M[k+1,j](k={i,i+1,...j-1})

         

 1 //括号匹配问题 求最大子长 M[i,j]=min(M[i,j],M[i,k]+M[k+1,j]
 2     class Program
 3     {
 4         static void Main(string[] args)
 5         {
 6             string S = "((]";
 7             int[,] M = new int[S.Length, S.Length];
 8             for (int i = 0; i < S.Length; i++)
 9                 for (int j = 0; j < S.Length; j++)
10                     M[i, j] = -1;
11             Console.WriteLine(NeedLength(0, S.Length - 1, S, M));
12             for (int i = 0; i < S.Length; i++)
13             {
14                 Console.WriteLine();
15                 for (int j = 0; j < S.Length; j++)
16                     Console.Write(M[i, j] + "  ");
17             }
18             Console.Read();
19         }
20         //判定是否匹配
21         public static bool isMatch(char x, char y)
22         {
23             bool flag = false;
24             if ((x == '(' && y == ')') || (x == '[' && y == ']'))
25                 flag = true;
26             return flag;
27         }
28         /// <summary>
29         /// 求解需要的最少括号数
30         /// </summary>
31         /// <param name="i">从I开始</param>
32         /// <param name="j">到j结束</param>
33         /// <param name="S">匹配数组</param>
34         /// <param name="M">保存i---j需要次数的数组</param>
35         /// <returns></returns>
36         public static int NeedLength(int i, int j, string S, int[,] M)
37         {
38             int ans = 10000;
39             if (M[i, j] != -1)
40                 return M[i, j];
41             if (i == j)
42             {
43                 return 1;
44             }
45             if (i > j)
46                 return 0;
47             if (isMatch(S[i], S[j]))//如果匹配,则直接i往后移,j往前移
48             {
49                 ans = Math.Min(ans, NeedLength(i + 1, j - 1, S, M));
50             }
51             for (int k = i ; k < j; k++)//求解哪个分解之后,使得结果最小化
52             {
53                 ans = Math.Min(ans, NeedLength(i, k, S, M) + NeedLength(k + 1, j, S, M));
54             }
55             M[i, j] = ans;
56             return M[i, j];
57         }
58     }
View Code
原文地址:https://www.cnblogs.com/xiaoyi115/p/3175354.html