NYOJ15括号匹配

NYOJ15括号匹配

括号匹配(二)

时间限制:1000 ms  |  内存限制:65535 KB

难度:6

描述
给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来。
如:
[]是匹配的
([])[]是匹配的
((]是不匹配的
([)]是不匹配的
输入
第一行输入一个正整数N,表示测试数据组数(N<=10)
每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度不超过100
输出
对于每组测试数据都输出一个正整数,表示最少需要添加的括号的数量。每组测试输出占一行
样例输入
4
[]
([])[]
((]
([)]
样例输出
0
0
3
2
来源
《算法艺术与信息学竞赛》

分析

二维数组dp[i][j] 表示字符串s的第i..j字符需要最少括号数,下面是具体的表示:

当i= j的时候,只有一个字符,那么,只要匹配一个字符就行了,所以,dp[i][i] = 1

如果,当i < j的时候,s[i] = s[j]  那么,dp[i][j] = min(dp[i][j],dp[i+1][j+1]),其中,假设i <= k < j 状态转移方程为 dp[i][j] = min(dp[i][j],d[i][k] + dp[k+1][j])

换个角度,换个方向

分析:我们求出这个串的最大匹配,然后串的总长度-最大匹配就是答案。

方法1:首先能想到的是转化成LCS(最长公共子序列),枚举中间点,求所有的LCS中的最大值 * 2就是最大匹配。但是复杂度较高,光LCS一次就O(n^2)的复杂度。

方法2:

首先考虑怎么样定义dp让它满足具有通过子结构来求解、

定义dp [ i ] [ j ] 为串中第 i 个到第 j 个括号的最大匹配数目

那么我们假如知道了 i 到 j 区间的最大匹配,那么i+1到 j+1区间的是不是就可以很简单的得到。

那么 假如第 i 个和第 j 个是一对匹配的括号那么dp [ i ] [ j ] = dp [ i+1 ] [ j-1 ] + 2 ;

那么我们只需要从小到大枚举所有 i 和 j 中间的括号数目,然后满足匹配就用上面式子dp,然后每次更新dp [ i ] [ j ]为最大值即可。

更新最大值的方法是枚举 i 和 j 的中间值,然后让 dp[ i ] [ j ] = max ( dp [ i ] [ j ] , dp [ i ] [ f ] + dp [ f+1 ] [ j ] ) ;

 1 #include <stdio.h>
 2 #include <string.h>
 3
 4 #define min(x,y) (x < y ? x : y)
 5 #define MAX 101
 6
 7 int dp[MAX][MAX];
 8
 9 bool cmp(int n,int m)
10 {
11     if((n == ‘(‘&&m == ‘)‘)||(n == ‘[‘&&m == ‘]‘))
12     return 1;
13     else
14     return 0;
15 }
16
17 int main(void)
18 {
19     int n,m,i,j,k;
20     char str[101];
21     scanf("%d",&n);
22     while(n--)
23     {
24         scanf("%s",str);
25         int length = strlen(str);
26         memset(dp,0,sizeof(dp));
27         for(i = 0; i < length; i++)
28         {
29             dp[i][i] = 1;
30         }
31         //区间dp常用dp套路
32         for(m = 1; m < length; m++)//枚举的串长度
33         {
34             for(i = 0; i < length - m; i++)//起点
35             {
36                 j = i + m;//终点
37                 dp[i][j] = MAX; //初始值
38                 if(cmp(str[i],str[j]))
39                 dp[i][j] = min(dp[i][j],dp[i+1][j-1]);//消去匹配的括号
40                 //枚举中间点
41                 for(k = i; k < j; k++)
42                 {
43                    dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]);
44                 }
45             }
46         }
47         printf("%d\n",dp[0][length-1]);
48     }
49     return 0;
50 }
时间: 2024-10-10 21:59:21

NYOJ15括号匹配的相关文章

NYOJ15|括号匹配(二)|区间DP|Elena

括号匹配(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:6 描述 给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来. 如:[]是匹配的([])[]是匹配的((]是不匹配的([)]是不匹配的 输入 第一行输入一个正整数N,表示测试数据组数(N<=10)每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度

【栈思想、DP】NYOJ-15 括号匹配(二)

括号匹配(二) 描述 给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来.如:[]是匹配的([])[]是匹配的((]是不匹配的([)]是不匹配的 输入 第一行输入一个正整数N,表示测试数据组数(N<=10)每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度不超过100 输出 对于每组测试数据都输出一个正整数,表示最少需要添加的括

NYOJ15 括号匹配(二)

经典的动态规划题 这道题感觉确实有一定难度,感觉自己的dp学的弱爆了!以后还要努力啊! 括号匹配(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:6 描述 给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来.如:[]是匹配的([])[]是匹配的((]是不匹配的([)]是不匹配的 输入 第一行输入一个正整数N,表示测试数据组数(N<

nyoj 括号匹配

这个方程有两种形式,本文采用 if(s[i]=s[j]) dp[i][j]=d[i-1][j-1] dp[i][j]=min(dp[i][k]+dp[k+1][j],dp[i][j]) (i=<k<j) 其实与另一种方法比较:根据j的所有匹配情况取最小值 1.i到j无匹配,取为dp[i][j-1]+1 2.列举所有匹配情况 dp[i][k-1]+dp[k+1][j] 取上述所有情况最小值 两者都能获得正确的结果. 同时两者的初始化为 dp[i][j]==1 if(i==j) 规划方向为:  

括号匹配问题(顺序栈实现)

本周老师作业留了两个.先上传一个吧.那个有时间我再传上来~ 本周的要求: 1.给出顺序栈的存储结构定义. 2.完成顺序栈的基本操作函数. 1)      初始化顺序栈 2)      实现入栈和出栈操作 3)      实现取栈顶元素和判空操作 括号匹配问题 3.编写主函数实现基本操作函数功能,并设置测试数据,测试合法和非法数据的输出结果. 4.程序调试运行并保存输出结果. 5.整理并提交实验作业. 1 #include <cstdio> 2 #include <cstring>

堆栈_括号匹配

class Solution { public: bool isValid(string s) { if(s.empty()) return false; stack<int> s1; int n=s.size(); for(int i=0;i<n;i++) { if(s[i]=='('||s[i]=='['||s[i]=='{') s1.push(s[i]); else if(s1.empty()) return false; else if((s[i]==')'&&s

括号匹配(二)

括号匹配(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:6 描述 给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来.如:[]是匹配的([])[]是匹配的((]是不匹配的([)]是不匹配的 输入 第一行输入一个正整数N,表示测试数据组数(N<=10)每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度不

动态规划(2)--括号匹配(二)

括号匹配(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:6 描述给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来.如:[]是匹配的([])[]是匹配的((]是不匹配的([)]是不匹配的 输入 第一行输入一个正整数N,表示测试数据组数(N<=10)每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度不超

行编辑程序、括号匹配检验

行编辑程序.括号匹配检验程序都是利用的栈的数据结构.而这两个 小程序也非常好的显示了栈先进后出的思想.由于程序本身很简短.清晰,所 以也就不做多的解释了,直接上代码了. 行编辑程序: #include<iostream> #include<stack> using namespace std; int main() { stack<char> sta; char ch = getchar(); while(ch!=EOF) { while(ch!=EOF&&am