//11208462 c00h00g 1141 Accepted 428K 0MS G++ 1601B 2013-01-25 16:44:59
//其实黑书中只需要相等和分割两部分就行了。即只需要判断brac[i][j]=='()'或'[]'的情况和枚举分割点的情况
//此题黑书中已经给出了比较具体的解释,关键是如何输出,其实我们只需要使用path[i][j]来记录分割点k,然后
//递归输出就行了。这让我想到了算法导论中计算矩阵相乘最少次数的那道题目,那一题也是记录了一个分割点。
//记录了分割点,然后分别对分割点左边和右边递归调用print函数就可以了
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define INF 0x7fffffff
char brac[105];
int dp[105][105];
int path[105][105];
void get_dp(int n){
for(int i=1;i<=n;i++){
dp[i][i]=1;
dp[i][i-1]=0;
}
for(int len=1;len<n;len++){
for(int i=1;i<=n-len;i++){
int j=i+len;
dp[i][j]=INF;
if((brac[i]=='('&&brac[j]==')')||(brac[i]=='['&&brac[j]==']')){
if(dp[i][j]>dp[i+1][j-1]){
dp[i][j]=dp[i+1][j-1];
path[i][j]=-1;
}
}
for(int k=i;k<=j-1;k++){
if(dp[i][j]>dp[i][k]+dp[k+1][j]){
dp[i][j]=dp[i][k]+dp[k+1][j];
path[i][j]=k;
}
}
}
}
}
void print(int i,int j){
if(i>j) return;
if(i==j){
if(brac[i]=='['||brac[i]==']')
printf("[]");
if(brac[i]=='('||brac[i]==')')
printf("()");
return;
}
int k=path[i][j];
if(k==-1){
if(brac[i]=='('){
printf("(");
print(i+1,j-1);
printf(")");
}
if(brac[i]=='['){
printf("[");
print(i+1,j-1);
printf("]");
}
}
else{
print(i,k);
print(k+1,j);
}
}
int main(){
while(gets(brac+1)){
int len=strlen(brac+1);
get_dp(len);
//printf("%d\n",dp[1][len]);
print(1,len);
printf("\n");
}
return 0;
}
POJ 1141
最新推荐文章于 2020-07-07 20:47:02 发布