http://poj.org/problem?id=1141
这是一道典型的动态规划题目,过去做过类似的,如POJ3391,思路几乎一摸一样,但是这道题目唯一比较讨厌的地方就是,得构造出最终的最优解,就是得显示出最优解的摸样,本来想通过做标记的方式,把DP的路径记录下来,后来感觉很麻烦,于是又加了一个bestStr[][]数组,元素类型是string,把每一个状态的形态记录了下来,bestStr[0][n-1]即是最优解,但是这样够早的话,可能附加操作比较多,因为每次都涉及很多字符串衔接的操作,导致最终居然超时。。。有时间,换一个方法实现以下好了,不用记忆搜索,换成循环递归实现以下,看看是否能摆脱超时。
代码如下:
#include<iostream>
#include<string>
using namespace std;
const int SIZE =101;
char arr[SIZE];
int dp[SIZE][SIZE];
string bestStr[SIZE][SIZE];
int func(int i,int j){
if(dp[i][j]>=0)//dp[i][j] 已经计算过,直接返回,记忆搜索
return dp[i][j];
if(i>j){//此情况为空集
dp[i][j]=0;
bestStr[i][j]="";
return 0;
}
if(i==j){//此情况为一个元素
dp[i][j]=1;
if(arr[i]=='('||arr[i]==')')
bestStr[i][i]="()";
else
bestStr[i][i]="[]";
return 1;
}
int min = 100,temp;
string tempStr ;
if(arr[i]=='('&&arr[j]==')'){
min=func(i+1,j-1);
tempStr = "("+bestStr[i+1][j-1]+")";
}
else if(arr[i]=='['&&arr[j]==']'){
min=func(i+1,j-1);
tempStr = "["+bestStr[i+1][j-1]+"]";
}
int temp1=func(i+1,j)+1;
int temp2=func(i,j-1)+1;
if(temp1<min){
min=temp1;
if(arr[i]=='(')
tempStr=bestStr[i+1][j]+")";
else if(arr[i]=='[')
tempStr=bestStr[i+1][j]+"]";
/*else if(arr[i]==')')
tempStr="()"+bestStr[i+1][j];
else if(arr[i]==']')
tempStr="[]"+bestStr[i+1][j];*/
}
if(temp2<min){
min=temp2;
if(arr[j]==')')
tempStr="("+bestStr[i][j-1];
else if(arr[j]==']')
tempStr="["+bestStr[i][j-1];
/*else if(arr[j]=='(')
tempStr=bestStr[i][j-1]+"()";
else if(arr[j]=='[')
tempStr=bestStr[i][j-1]+"[]";*/
}
for(int k=i;k<=j-1;k++){
temp=func(i,k)+func(k+1,j);
if(temp<=min){
min=temp;
tempStr=bestStr[i][k]+bestStr[k+1][j];
}
}
dp[i][j]=min;
bestStr[i][j]=tempStr;
return dp[i][j];
}
int main(){
//while(cin>>arr){
cin>>arr;
memset(dp,-1,sizeof(dp));
func(0,strlen(arr)-1);
cout<<bestStr[0][strlen(arr)-1]<<endl;
// cout<<func(0,strlen(arr)-1)<<" "<<bestStr[0][strlen(arr)-1]<<endl;
// }
return 0;
}