Sample Input
((())) ()()() ([]]) )[)( ([][][) end //结束
Sample Output
6 //三对六个 6 4 0 6
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define INF 0x3f3f3f3f #define MAX 10000 int dp[MAX/10][MAX/10];//i到j位置匹配的括号数--直接求匹配的括号个数 char str[MAX]; bool check(char a,char b) { if(a=='(' && b==')') return true; if(a=='[' && b==']') return true; return false; } int main() { int len,l,i,j,k; while(~scanf("%s",str)) { if(!strcmp(str,"end")) break; memset(dp,0,sizeof(dp)); len=strlen(str); for(i=0; i<len; i++) { //dp[i][i]=0; if(check(str[i],str[i+1])) dp[i][i+1]=2; } for(l=2; l<len; l++) { for(i=0; i<len-1; i++) { j=i+l; //dp[i][j]=INF; if(check(str[i],str[j])) dp[i][j]=2+dp[i+1][j-1]; for(k=i; k<j; k++) dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]); } } printf("%d\n",dp[0][len-1]); } return 0; }
逆向思路,总长度-最小的不匹配个数
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define INF 0x3f3f3f3f #define MAX 10000 int dp[MAX/10][MAX/10];//i到j位置不匹配的括号数 char str[MAX]; bool check(char a,char b) { if(a=='(' && b==')') return true; if(a=='[' && b==']') return true; return false; } int main() { int len,l,i,j,k; while(~scanf("%s",str)) { if(!strcmp(str,"end")) break; //memset(dp,0,sizeof(dp)); for(i=0;i<len;i++) dp[i][i]=1; len=strlen(str); for(l=1;l<len;l++) { for(i=0;i<len-1;i++) { j=i+l; dp[i][j]=INF; if(check(str[i],str[j])) dp[i][j]=dp[i+1][j-1]; for(k=i;k<j;k++) dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]); } } printf("%d\n",len-dp[0][len-1]); } return 0; }