poj 1141 Brackets Sequence

本文介绍如何使用动态规划解决括号匹配问题,并详细解释了状态转移方程的运用,通过实例展示了算法的实现过程。

感想:较好的入门题,关键这里可以让你学到记录路径的方法,也可以算做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 100000000
using 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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值