POJ 1141 - Brackets Sequence 区间DP

            题意:

                     括号由( )或者[ ]组成..并且当s为一个合法的括号序列...那么(s)和[s]都是合法的括号序列..现在给出一列括号..请添加最少的括号让这个括号序列合法.并且输出添加过括号后合法的括号序列..

            题解:

                     容易想到区间DP...dp[l][r]代表将区间[l~r]变成合法的括号序列所需添加的最少括号数...初始值对于每个位置dp[i][i]=1..转移..若当前s[l]可以和s[r]配对..则先将其赋值为dp[l+1][r-1].(注意..比如dp[1][2]时..会变成dp[2][1]..所以初始时将所有的dp[ ][ ]初始成0)...否则其先赋值为无穷大..然后枚举终点k=l~r-1...看dp[l][k]+dp[k+1][r]能否将dp[l][r]更新得更小..那么更新...如此得到了整个区间所需要的最少添加括号次数...

                     而要输出合法的括号序列..就需要一边更新一边转移了...为了输出的方便...用递归回朔很直接..


Program:

#include<iostream>      
#include<algorithm>      
#include<stdio.h>      
#include<string.h>    
#include<time.h>   
#include<map>   
#include<math.h>      
#include<queue>      
#define MAXN 105
#define MAXM 1000005 
#define oo 1000000007      
#define ll long long      
#define MOD 1000000  
using namespace std;  
char s[MAXN];
int dp[MAXN][MAXN],pre[MAXN][MAXN];
void dfs(int l,int r)
{  
      if (l>r) return;
      if (l==r)
      {
             if (s[l]=='(' || s[l]==')') printf("()");
                                   else  printf("[]");
             return;
      }
      int x=pre[l][r]; 
      if (!x)  
             printf("%c",s[l]),
             dfs(l+1,r-1),
             printf("%c",s[r]); 
      else
             dfs(l,x),dfs(x+1,r); 
}
int main()     
{       
      int n,i,L,l,r,k;
      freopen("input.txt","r",stdin);
      freopen("output.txt","w",stdout); 
      gets(s+1),n=strlen(s+1);
      memset(dp,0,sizeof(dp));
      memset(pre,0,sizeof(pre));
      for (i=1;i<=n;i++) dp[i][i]=1;
      for (L=2;L<=n;L++)
        for (l=1;l<=n-L+1;l++)
        {
               r=l+L-1;
               if (s[l]=='(' && s[r]==')' || s[l]=='[' && s[r]==']') 
                        dp[l][r]=dp[l+1][r-1];
                   else dp[l][r]=oo;
               for (k=l;k<r;k++)
                   if (dp[l][r]>dp[l][k]+dp[k+1][r])
                   {
                          dp[l][r]=dp[l][k]+dp[k+1][r];
                          pre[l][r]=k;
                   }
        }
      dfs(1,n);
      printf("\n");
    //  printf("%d\n",dp[1][n]); 
      return 0;    
}    


你可能感兴趣的:(POJ 1141 - Brackets Sequence 区间DP)