poj 1141 Brackets Sequence

来源:互联网 发布:老九门社交软件 编辑:程序博客网 时间:2024/04/29 12:28

感想:较好的入门题,关键这里可以让你学到记录路径的方法,也可以算做dp记路径的入门题了吧。


思路:   这题的思路关键在于   (A) 或(B)  AB这几种请况,所以在dp的过程中 要找这几种的最小值,


首先   dp[ i ][ i ]肯定是1,因为只有一个单括号的话,必须要来一个括号来进行匹配;


状态转移方程   dp[ i ][ j ] =  min(dp[ i ][ z ] +dp[ z ][ j ] )   i<=z<j      如果str[ i ]和str[ j ]是一对匹配的字符串   则->


dp[ i ][ j ] = min(dp[ i+1 ][ j-1 ],  dp[ i ][ j ] );   这里必须明白   无论str[ i ]是否和str[ j ]匹配  都需要去求其分割的结果


比如这种情况就需要   (  ... )(  ... )求这2中情况的最小值



#include<cstdio>#include<cstring>#include<iostream>#include<string>#define min(aa,bb) (aa)>(bb)?(bb):(aa)#define MAXN 105#define INF 100000000using namespace std;string str;int size;int dp[MAXN][MAXN];int pos[MAXN][MAXN];void DP(){  size = str.size();  for(int i=0;i<size;++i)  dp[i][i] = 1;//一个字符的时候必须得匹配另外一个  for(int k=1;k<size;++k)  for(int i=0,j=i+k;j<size&&i<size;++j,++i)  {      dp[i][j] = INF;    if((str[i]=='('&&str[j]==')')||(str[i]=='['&&str[j]==']'))    {        if(k==1)        {        dp[i][j] = 0;        pos[i][j] = -1;        }        else//这里i+1可能比j-1大,所以需要加个判断        {         dp[i][j] = dp[i+1][j-1];         pos[i][j] = -1;        }    }    for(int e=i;e<j;++e)    if(dp[i][e]+dp[e+1][j]<dp[i][j])    {     dp[i][j] = dp[i][e] + dp[e+1][j];     pos[i][j] = e;    }  }}void print(int l,int r){    if(l<=r)    {      if(l==r)      {        if(str[l]=='('||str[l]==')')        cout<<"()";        else        cout<<"[]";      }      else      {      if(pos[l][r]==-1)      {        cout<<str[l];        print(l+1,r-1);        cout<<str[r];      }      else      {       print(l,pos[l][r]);       print(pos[l][r]+1,r);      }      }    }}int main(){    cin>>str;    DP();    print(0,str.size()-1);    cout<<endl;    return 0;}


原创粉丝点击