poj1141 Brackets Sequence

来源:互联网 发布:js的基本数据类型 编辑:程序博客网 时间:2024/06/05 18:05

    看到这道题,第一感觉就是区间dp,但重要的就是如何状态转移了。

对于给定的串S,可分以下三种情况讨论:

1.S形如(S')或[S'],则只要把S'变成规则的就行;

2.S形如(S'则只需将S'变成规则的,然后在右边添上')';

3.对于S形如S')或S']或[S',方法同上。

对于任何一个串S,都可将它分成两部分S1,S2,若S1,S2规则,则S也规则。

说到这里,状态转移方程基本就就出来了。

#include<iostream>#include<cstring>using namespace std;const int maxn=100;char s[maxn+5];int dp[maxn][maxn];int c[maxn][maxn];//记录当前状态的决策,用于输出路径//c[i][j]=-1,-2,-3分别表示那特殊情况的决策,若c[i][j]>0,则表示区间[i,j]的分割点为c[i][j]. int len;void print(int i,int j){if(i>j)return;if(c[i][j]<0){if(c[i][j]==-1){printf("%c",s[i]);print(i+1,j-1);printf("%c",s[j]);}if(c[i][j]==-2){printf("%c",s[i]);print(i+1,j);if(s[i]=='(')printf(")");elseprintf("]");}if(c[i][j]==-3){if(s[j]==')')printf("(");elseprintf("[");print(i,j-1);printf("%c",s[j]);}return;}print(i,c[i][j]);print(c[i][j]+1,j);}int main(){int i,j,k,Case;Case=0;while(gets(s))//用scanf不行,问题还是出在scanf对空格的处理上 {Case++;len=strlen(s);for(i=1;i<len;i++)dp[i-1][i]=0;for(i=len-1;i>=0;i--)for(j=i;j<len;j++){dp[i][j]=100000;if(s[i]=='('&&s[j]==')'||s[i]=='['&&s[j]==']'){c[i][j]=-1;dp[i][j]=dp[i+1][j-1];}else if(s[i]=='('||s[i]=='['){c[i][j]=-2;dp[i][j]=1+dp[i+1][j];}else if(s[j]==')'||s[j]==']'){dp[i][j]=1+dp[i][j-1];c[i][j]=-3;}for(k=i;k<j;k++){if(dp[i][j]>dp[i][k]+dp[k+1][j]){c[i][j]=k;dp[i][j]=dp[i][k]+dp[k+1][j];}}}//printf("%d. %d\n",Case,dp[0][len-1]);print(0,len-1);printf("\n");}return 0;}


原创粉丝点击