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]); }