uva1626 Brackets sequence
阿新 • • 發佈:2017-08-22
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