括号配对

https://loj.ac/problem/10150

题目描述

  给出一个由小括号和中括号组成的括号序列,求最少添加几个括号可以是括号完全匹配。

思路

  我们考虑用\(f[i][j]\)表示在\(i\sim j\)段的答案,那么对于它可以由较短长度的序列转移过来,我们分为三种情况:1、序列两端恰好匹配。2、由\(j-i\)长度的转移过来。3、把序列分为两段计算贡献。直接\(dp\)求即可。

代码

#include <bits/stdc++.h>
using namespace std;
char s[110];
int f[110][110];
int main() 
{
	scanf(" %s",s+1);
	int n=strlen(s+1);
	memset(f,127,sizeof(f));
	for(int i=1;i<=n;i++)
		f[i][i]=1;
	for(int i=1;i<=n;i++)
		for(int j=1;j<i;j++)
			f[i][j]=0;
	for(int len=2;len<=n;len++)
		for(int l=1;l<=n-len+1;l++)
		{
			int r=l+len-1;
			if((s[l]=='('&&s[r]==')')||(s[l]=='['&&s[r]==']'))
				f[l][r]=min(f[l][r],f[l+1][r-1]);
			f[l][r]=min(f[l][r],f[l+1][r]+1);
			f[l][r]=min(f[l][r],f[l][r-1]+1);
			for(int k=l+1;k<r;k++)
				f[l][r]=min(f[l][r],f[l][k]+f[k+1][r]);
		}
	printf("%d",f[1][n]);
}

posted @ 2019-11-11 19:37  fbz  阅读(105)  评论(0编辑  收藏  举报