POJ1141 Brackets Sequence

题目大意:定义一些规则序列:如果S是规则序列,那么[S]或者(S)也是规则序列,如果A和B都是规则序列,那么AB是规则序列。给出含有圆括号"()"和方括号"[]"的字符串

求添加最少括号的规则序列,并打印出来。

思路:含有重复子问题,递归动机的DP。

当字符串中ww[i]=='(' && ww[j]==')'  或者  ww[i]=='['&&ww[j]==']',那么显然只需要看dp[i+1][j-1]的结果即可。

dp[i][j] = min(dp[i][k] + dp[k + 1][j]), i<=k < j;

然后通过二分思想分呀分,找到中间使得dp【i】【j】最小的k,并记载下来,便于递归打印规则序列。


AC Program:

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
#define inf 1000000000
char ww[108];
int dp[108][108];
int pos[108][108];
//dp[i][j]indicate:the characters from i to j
//the smallest length added. 
void print(int a ,int b){
     //cout<<a<<" "<<b<<endl;
     
     if(a==b){
        if(ww[a]=='(' ||ww[a]==')'){//lost the last half
           printf("()");               
        }         
        else{
           printf("[]");     
        }
     }
     if(a>=b){return;}//can't set a  flag cause all leaves should be printed. 
     if(pos[a][b]==-1){
         if(ww[a]=='('){
            printf("(");
            print(a+1,b-1);
            printf(")");               
         }              
         else{
            printf("[");
            print(a+1,b-1);
            printf("]");     
         }    
     }
     else{
          print(a,pos[a][b]);
          print(pos[a][b]+1,b);      
     }
}
int main(){
scanf("%s",ww+1);
int n=strlen(ww+1);//from 1 to start
for(int i=1;i<=n;i++){
  for(int j=1;j<=n;j++){
     dp[i][j]=inf;        
  } 
  dp[i][i-1]=0;
  dp[i][i]=1;
} 
memset(pos,-1,sizeof(pos));   
for(int p=1;p<=n-1;p++){
   for(int i=1;i<=n-p;i++){
      int j=i+p;
      if((ww[i]=='('&&ww[j]==')')||(ww[i]=='[' && ww[j]==']')){
         //dp[i][j]=min(dp[i][j],dp[i+1][j-1]);                 
         if(dp[i][j]>dp[i+1][j-1]){
            dp[i][j]=dp[i+1][j-1];
            pos[i][j]=-1;                          
         }
      }
      for(int k=i;k<=j-1;k++){
         //dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]);       
         if(dp[i][j]>dp[i][k]+dp[k+1][j]){
              dp[i][j]=dp[i][k]+dp[k+1][j];
              pos[i][j]=k;                                
         }
      }
   }        
}
print(1,n);
printf("\n");
//cout<<pos[1][n]<<endl;
//printf("%d\n",dp[1][n]);
//system("pause");
return 0;} 



你可能感兴趣的:(POJ1141 Brackets Sequence)