カッコ
時間制限: 1000ミリ秒 | メモリ制限: 65536kも | |
合計提出: 17416 | 受け入れ: 9016 |
説明
私たちは、「通常の括弧」シーケンスの次の誘導定義を与えます:
- 空のシーケンスは、通常の括弧配列であり、
- 場合 sは 正規ブラケットシーケンスであり、次いで(S)及び[ S ]は、通常のブラケット配列であり、そして
- 場合 及び bは 正規ブラケット配列で、次いで ABは 正規ブラケット配列です。
- 他のシーケンスは、通常の括弧配列であります
たとえば、次の文字配列の全ては、通常の括弧配列であります:
(), [], (()), ()[], ()[()]
次の文字列ではありませんしながら。
(, ], )(, ([)], ([(]
文字のブラケットシーケンスを考える 1 2 ... 、あなたの目標は、のサブシーケンスである最長の定期的なブラケットシーケンスの長さを見つけるためにある のを。つまり、あなたが最も検索したい メートルを ようにインデックスの I 1、 I 2、...、 イム ここで、1≤ I 1 < I 2 <... < イム ≤ nは、 aiを 1 愛 2 ... 目的は 、通常のブラケットシーケンスです。
初期シーケンスを考えると ([([]])]
、最長の定期的なブラケットのサブシーケンスがあります [([])]
。
入力
入力テストファイルは、複数のテストケースが含まれています。各入力テストケースは、文字だけを含む単一のラインで構成され (
、 )
、 [
、および ]
、各入力テストは1以上100以下の長さを有するであろう。ファイルの終わりには、単語「終わり」を含む行でマークされ、処理されるべきではありません。
出力
各入力の場合のために、プログラムは、単一の行に可能な限り長い正規ブラケットサブシーケンスの長さを印刷しなければなりません。
サンプル入力
((()))
()()()
([]])
)[)(
([][][)
end
サンプル出力
6
6
4
0
6
#include<stdio.h>
#include<string.h>
#define maxn 110
int dp[maxn][maxn];
int max(int x,int y){
return x>y?x:y;
}
int main(){
char s[maxn];
while(scanf("%s",s)!=EOF){
int i,j,k,len,n;
if(s[0]=='e') break;
memset(dp,0,sizeof(dp));
n=strlen(s);
for(len=1;len<=n;len++){
for(i=0;i<n;i++){
j=len+i-1;
//if(s[i]==')'||s[i]==']')
dp[i][j]=dp[i+1][j]; //第i个在这段区间没有匹配
//else
for(k=i+1;k<=j;k++){ //第i个与第k个位置匹配上时,状态如下
if((s[k]==')'&&s[i]=='(')||(s[k]==']'&&s[i]=='['))
dp[i][j]=max(dp[i][j],dp[i+1][k-1]+dp[k+1][j]+2);
}
}
}
printf("%d\n",dp[0][n-1]);
}
return 0;
}