1. 程式人生 > >uva1626 Brackets sequence

uva1626 Brackets sequence

rac bracket 題目 get 輸出 bool int 最短 iostream

題目大意:

給一個有小括號和中括號組成的序列,滿足題中的三個條件時,是合法的。不滿足時是不合法的,問將一個不合法的序列最少添加幾個括號可以使之變成合法的。輸出最短合法序列。

/*
    比較坑的一道題,wa無數次。。。
    思路就是區間dp的一般思路,dp[i][j]表示區間i~j之間最少加幾個字符才能匹配成立 
    pre[i][j]表示在區間i~j中的兩個子區間左端點 
*/
#include<cstdio> 
#include<cstring>
#include<iostream>
using namespace std;
const int inf=1<<29; const int maxn=110; char str[maxn]; int n,dp[maxn][maxn]; pair<int,int>pre[maxn][maxn]; bool check(int i,int j){ if((str[i]==(&&str[j]==))||str[i]==[&&str[j]==]) return true; return false; } void dfs(int l,int r){
if(l>r)return; if(l==r){ if(str[l]==[||str[l]==])printf("[]"); if(str[l]==(||str[l]==))printf("()"); return; } if(check(l,r)&&dp[l][r]==dp[l+1][r-1]){ printf("%c",str[l]); dfs(l+1,r-1); printf("%c",str[r]);
return; } int sl=pre[l][r].first; int sr=pre[l][r].second; dfs(sl,sr); dfs(sr+1,r); } int main(){ freopen("Cola.txt","r",stdin); int T; scanf("%d",&T); getchar(); while(T--){ memset(pre,-1,sizeof(pre)); gets(str); gets(str); n=strlen(str); for(int i=0;i<n;i++)dp[i][i]=1; for(int j=1;j<n;j++){ for(int i=0;i+j<n;i++){ dp[i][i+j]=inf; if(check(i,i+j)){ dp[i][i+j]=dp[i+1][i+j-1]; pre[i][i+j]=make_pair(i+1,i+j-1); } for(int k=0;k<=j;k++){ if(dp[i][i+j]>dp[i][i+k]+dp[i+k+1][i+j]){ dp[i][i+j]=dp[i][i+k]+dp[i+k+1][i+j]; pre[i][i+j]=make_pair(i,i+k); } } } } dfs(0,n-1); printf("\n"); if(T)printf("\n"); } return 0; }

uva1626 Brackets sequence