1141 DP 括号序列

自底向上递推,打表,分析补全括号的各种最优情况。

#include <iostream>

#include <string>

#include <iomanip>

using namespace std;

#define max 110

#define INF 10000000;

int d[max][max];

string ans[max][max];

char s[110];

int n;

char rev(char a)

{

	if(a=='(') return ')';

	else if(a==')') return '(';

	else if(a=='[') return ']';

	else if(a==']') return '[';

}

void dp()

{

	for(int i=1;i<=n;i++){

		d[i][i-1]=0;

		d[i][i]=1;

		if(s[i]==')'||s[i]=='(') ans[i][i]="()";

		else ans[i][i]="[]";

	} 

	for(int p=1;p<=n-1;p++)

	{

		for(int i=1;i<=n-p;i++){

			int j=i+p;

			d[i][j]=INF;

			if((s[i]=='('&&s[j]==')') || (s[i]=='['&&s[j]==']'))

			{

				if(d[i][j]>d[i+1][j-1])

				{

					d[i][j]=d[i+1][j-1];

					ans[i][j]=s[i]+ans[i+1][j-1]+s[j];

				}

			}

			if(s[i]=='('||s[i]=='[')

			{	

				if(d[i][j]>d[i+1][j]+1){

					d[i][j]=d[i+1][j]+1;

					ans[i][j]=s[i]+ans[i+1][j]+rev(s[i]);

				}

			}

			if(s[j]==')'||s[j]==']'){

				if(d[i][j]>d[i][j-1]+1){

					d[i][j]=d[i][j-1]+1;

					ans[i][j]=rev(s[j])+ans[i][j-1]+s[j];

				}

			}

			for(int k=i;k<=j-1;k++){

				if(d[i][j]>d[i][k]+d[k+1][j]){

					ans[i][j]=ans[i][k]+ans[k+1][j];

					d[i][j]=d[i][k]+d[k+1][j];

				}

			}

		}

	}

}

//void print()

//{

//	for(int i=1;i<=n;i++){

//		for(int j=1;j<=n;j++)

//			cout<<setw(12)<<d[i][j]<<ans[i][j];

//		cout<<endl;

//	}

//	cout<<endl;	

//}



int main()

{

	gets(s+1);

	n=strlen(s+1);

	dp();

	cout<<ans[1][n]<<endl;

	return 0;

}

 

你可能感兴趣的:(dp)