DP之Brackets Sequence

Brackets Sequence 题目大意:给你一贯括号序列(只包含小括号和中括号),让你找出长度最小的regular brackets sequence包含此子序列.其中的regular brackets sequence定义如下: 1)空序列是一个regular brackets sequence; 2)如果s是一个regular brackets sequence,那么[s] 也是一个regular brackets sequence,(s)也是一个regular brackets sequence. 3)如果A,B都是regular brackets sequence,那么AB也是一个regular brackets sequence. 例如:()、[]、()[] 、([]) 、([])()[()]都是regular brackets sequence。 而[[[、 (((((、 ([)] 则都不是regular brackets sequence。其中以“([)]”为例,包含它最小的regular brackets sequence有两个:()[()]或者是([])[].而你只要输出其中一个就行。 好了,题目题意讲完了,应该理解了吧。下面开始分析: 这个问题一眼就可以看出是DP题,为什么呢?因为很明显这个问题可以根据它定义中的(2)和(3)这两条性质划分出更小的子问题。也就是说,一个序列如果是AB形式的话,我们可以划分为A,B两个子问题;而如果序列是[A]或者(A)的形式,我们可以把它降为分析A即可。分解的底层就是剩下一对[]或者()或者是只剩下一个单字符就停下不再分解。当剩下的是一对匹配的()或者[]时,我们不必添加如何括号,因为这已经匹配,而对于只剩下最后一个单字符,我们需要对它配一个字符,使它配对,如(就配上),]就配上[,依此类推。 那么这题的状态转移方程就很容易列出来了,用a[i,j]表示从位置i到位置j所需要插入的最小字符数,明显有状态转移方程如下: a[i,j]=min(a[i,k]+a[k+1,j]) 其中i<=k#include <stdio.h>
#include <string.h>
int a[102][102],tag[102][102];
char str[128];
void search(int st,int end)
{
 if(st>end) return;
 else if(st==end){
  if(str[st]=='('||str[st]==')')
   printf("()");
  else printf("[]");
 }else{
  if(tag[st][end]==-1){
   if(str[st]=='('){
    printf("(");
    search(st+1,end-1);
    printf(")");
   }else{
    printf("[");
    search(st+1,end-1);
    printf("]");
   }
  }else{
   search(st,tag[st][end]);
   search(tag[st][end]+1,end);
  }
 }
}
int main()
{
 int len,i,st,j,k,s,tmp;
 while(scanf("%s",str)!=EOF)
 {
  len=strlen(str);
  for(i=0;i<len;a[i+1][i]=0,a[i][i]=1,i++);
  for(st=1;st<len;st++)
   for(i=0;i+st<len;i++)
   {
    j=i+st;
    tmp=0x7fffffff;
    if(str[i]=='('&&str[j]==')'||str[i]=='['&&str[j]==']')
     tmp=a[i+1][j-1];
    tag[i][j]=-1;
    for(k=i;k<j;k++)
    {
     s=a[i][k]+a[k+1][j];
     if(s<tmp)
      tmp=s,tag[i][j]=k;
    }
    a[i][j]=tmp;
   }
  search(0,len-1);
  printf("/n");
 }
 return 0;
}

 

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值