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

 

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章