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

原创粉丝点击