dp[i][j](j >= i)表示使从第i个字符到第j个字符匹配所需添加的最小括号数(有点绕口,但应该不难明白吧),那么这一状态可由下面得到:
- 若第i个字符到第j - 1个字符中没有与第j个字符匹配的括号,则所需的括号数加1,即f[i][j] = f[i][j - 1] + 1;
- 若第k(k < i)个字符与第j个字符匹配,那么所需括号数为第i到第k - 1个字符所需字符数加上第k + 1个字符到第i - 1个字符(注意可能存在多个字符与之匹配,即可能存在多个k),所需括号数f[i][j] = min(f[i][j], f[j][k - 1] + f[k + 1][i - 1])。
- # include<stdio.h>
- # include<string.h>
- char str[105];
- int is(int i,int j)
- {
- if(str[i]==']' && str[j]=='[') return 1;
- if(str[i]==')' && str[j]=='(') return 1;
- return 0;
- }
- int main()
- {
- int i,j,k,len,ncase,dp[105][105],min1;
- scanf("%d",&ncase);
- while(ncase--)
- {
- scanf("%s",str+1);
- len=strlen(str+1);
- for(i=0;i<=100;i++)
- {
- dp[0][i]=0;
- dp[i][0]=0;
- dp[i][i]=1;
- for(j=i+1;j<=100;j++)
- dp[i][j]=0;
- }
- for(i=1;i<=len;i++)
- {
- for(j=i-1;j>=1;j--)
- {
- min1=1+dp[i-1][j];
- for(k=j;k<=i-1;k++)
- {
- if(is(i,k))//如果这两个字符匹配
- {
- if(dp[i-1][k+1]+dp[k-1][j] < min1) min1=dp[i-1][k+1]+dp[k-1][j];
- }
- }
- dp[i][j]=min1;
- }
- }
- printf("%d\n",dp[len][1]);
- }
- return 0;
- }