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

 

posted @ 2012-07-11 15:25  HUJJ  阅读(421)  评论(0编辑  收藏  举报