括号配对
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]);
}