POJ 1141
来源:互联网 发布:直播刷人气软件 编辑:程序博客网 时间:2024/05/01 06:50
//11208462c00h00g1141Accepted428K0MSG++1601B2013-01-25 16:44:59//其实黑书中只需要相等和分割两部分就行了。即只需要判断brac[i][j]=='()'或'[]'的情况和枚举分割点的情况//此题黑书中已经给出了比较具体的解释,关键是如何输出,其实我们只需要使用path[i][j]来记录分割点k,然后//递归输出就行了。这让我想到了算法导论中计算矩阵相乘最少次数的那道题目,那一题也是记录了一个分割点。//记录了分割点,然后分别对分割点左边和右边递归调用print函数就可以了 #include<stdio.h>#include<stdlib.h>#include<string.h>#define INF 0x7fffffffchar 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;}