括号匹配(二)
时间限制:
1000 ms | 内存限制:
65535 KB 难度:
6
- 描述
- 给你一个字符串,里面只包含”(“,”)”,”[“,”]”四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来。
如:
[]是匹配的
([])[]是匹配的
((]是不匹配的
([)]是不匹配的
- 输入
- 第一行输入一个正整数N,表示测试数据组数(N<=10)
每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度不超过100
- 输出
- 对于每组测试数据都输出一个正整数,表示最少需要添加的括号的数量。每组测试输出占一行
- 样例输入
4 [] ([])[] ((] ([)]
- 样例输出
0 0 3
2
这是一个动态规划题目,解决问题的关键在于寻找dp[i][j]代表什么,还有递推公式是什么。
首先来说,对于任何一个字符串,需要从前到后计算其对应的答案,那么简单来说,i一定是从0~len-1
对于单个字符dp的值为1,很显然啊
对于两个字符还说,如果两个括号正好对应的话为0,不对应dp+1;
则对应的dp[i][j]表示从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])
#include <bits/stdc++.h> using namespace std; #define MAX 105 int dp[MAX][MAX]; int link(char a, char b) { if((a=='(' && b==')')||(a=='['&&b==']')) return 1; else return 0; } int main() { int t; scanf("%d",&t); while(t--) { string str; cin >> str; int len = str.size(); for(int i = 0; i < len; i++) { dp[i][i] = 1; } for(int m = 1; m < len; m++) { for(int i = 0; i+m < len; i++) { int j = i+m; dp[i][j] = MAX; if(link(str[i], str[j])) dp[i][j] = min(dp[i][j], dp[i+1][j-1]); for(int k = i; k < j; k++) { dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j]); } } } printf("%d\n", dp[0][len-1]); } return 0; }
这个题目理解起来不是很难,但是第一遍的写的时候出现了一个bug,怎么调都挑不出来很神奇