动归——括号匹配

nkoj 1507

水水的动归题一道。。。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int inf=2e9;
char str[305];
int s[305],f[305][305];
//f[i][j]表示将i到j变成合法串需要添加几个括号 
int main(){
	int i,n,j;
	scanf("%s",str+1);
	n=strlen(str+1);
	for(i=1;i<=n;i++){    	//将括号转化为数字,存在数组S里 
		if(str[i]=='(')s[i]=1;
		else if(str[i]=='[')s[i]=2;
		else if(str[i]=='<')s[i]=3;
		else if(str[i]=='{')s[i]=4;
		else if(str[i]==')')s[i]=5;
		else if(str[i]==']')s[i]=6;
		else if(str[i]=='>')s[i]=7;
		else if(str[i]=='}')s[i]=8;
	}
	for(i=1;i<=n;i++)f[i][i]=1;  //初值,单个括号需要加一个括号 
	for(i=n;i>0;i--)  //逆序 
	  for(j=i+1;j<=n;j++){
	  	 int minn=inf;
	  	 if(s[j]-s[i]==4)   //恰好配对 
		   minn=min(minn,f[i+1][j-1]);
	  	 else minn==min(minn,min(f[i][j-1],f[i+1][j]));
	  	 for(int k=i;k<j;k++) //枚举从i到j中任意点断开是否更优 
	  	 minn=min(minn,f[i][k]+f[k+1][j]);
	  	 f[i][j]=minn;
	  }
	  printf("%d",f[1][n]);
}
有一个小细节,如果i和j恰好配对,也要继续讨论,否则例如‘【】【】’就会被理解成‘】【’而需要添加两个括号。

你可能感兴趣的:(动归——括号匹配)