xynuoj 1804 bracket matching (2)

1804: Bracket matching (2)

Time Limit:  1 Sec   Memory Limit:  64 MB
[ Commit ][ Status ][ Discussion Board ]

Topic description

Given a string containing only "(",")","[","]" four symbols, how many brackets do you need to add at least to make these brackets match.
For example:
[] is matched
([]) [] is matched
((] is not matched
([)] is not matched

enter

Enter a positive integer N in the first line, indicating the number of test data groups (N<=10). Each group of test data has only one line, which is a string S. S only contains the above-mentioned four characters, and the length of S is different. More than 100

output

Output a positive integer for each set of test data, indicating the minimum number of parentheses to add. One line for each set of test output

sample input

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

Sample output

0
0
3
2

source

nyoj dynamic programming 

Interval DP

Turn:

The meaning of the question is to say that given a string containing four characters of '(', ')', '[', ']', it is judged that at least a few characters need to be added to match the parentheses of the given string.

Interval dynamic programming, let dp[i][j] represent the minimum characters that need to be added from position i to position j in string s (i <= j)

There are two cases:

1、dp[i][j] = dp[i+1][j] + 1; 

Indicates: there is no parenthesis matching s[i] between i and j, then a character must be added to match it, and the problem is transformed into: the minimum number of characters that need to be added from the i+1 position to the j position + 1.

2、dp[i][j] = min{ dp[i+1][k-1] + dp[k+1][j] }; (i < k <= j)

Representation: find a k between i and j so that s[i] matches s[k], then the problem is transformed into: the minimum number of characters to be added from i+1 to k-1 + from k The minimum number of characters to be added between +1 and j (ie dp[i+1][k-1] + dp[k+1][j] ). Since there may be more than one k, take the smallest among all the k cases.

After finding the two cases, and then finding the minimum value between the two, you can directly assign the initial value of dp[i][j] to dp[i+1][j]+1, and then proceed to the second case solution

After the dynamic transfer equation comes out, it is necessary to judge how many layers of loops to write and the starting point and end point of each layer of loops. It can be seen from the equation that there are 3 layers of loops (i, j, k). For dp[i][j], it must be First find the first j of the rows after i, so there are two methods of looping. I use the second method, which is relatively easy to understand. As shown below.

                 

                         Method 1: Update from left to right Method 2: Update from bottom to top

Initialization: add at least one character when there is only one character, so dp[i][i] = 1;


#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
char str[110];
int judge(int x,int y){//Judging whether str[x] and str[y] are paired
	if(str[x]=='('&&str[y]==')'||str[x]=='['&&str[y]==']')
	return 1;
	else
	return 0;
}
int main(){
	int N;
	scanf("%d",&N);
	int dp[110][110];
	while(N--){
		memset(dp,0,sizeof(dp));
		scanf("%s",str);
		int len=strlen(str);
		for(int i=0;i<len;i++){
			dp[i][i]=1;
		}
		for(int i=len-2;i>=0;i--){
			for(int j=i;j<len;j++){
				dp[i][j]=dp[i+1][j]+1;//赋初值为第一种情况(在i和j之间没有str[i]的),因为有两种情况并且最后要取两种情况的最小值,所以先给初始情况赋值为第一种情况 
				//(一共是两种情况,第一种是i和j之间没有字符可以匹配str[i],所以需要在i和j之间加一个括号,问题就转化为在第i+1和j之间需要加的括号数+1 
				//另一种是i和j之间本身就存在着和str[i]搭配的括号str[k],那么问题就转化为在第i+1和第k-1之间需要加的最小值和在k+1和j之间需要加的最小括号数的和)
				for(int k=i+1;k<=j;k++){
					if(judge(i,k)){//在i跟j之间存在着str[i]的配对括号 
						dp[i][j]=min(dp[i][j],dp[i+1][k-1]+dp[k+1][j]);//因为k可能有多个,所以在所有的情况中取最小的 
					}
				} 
			}
		}
		printf("%d\n",dp[0][len-1]);
	}
	return 0;
} 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324521109&siteId=291194637