1. 程式人生 > >【基礎練習】【區間DP】codevs3657 括號序列題解

【基礎練習】【區間DP】codevs3657 括號序列題解

題目描述 Description

我們用以下規則定義一個合法的括號序列:

(1)空序列是合法的

(2)假如S是一個合法的序列,則 (S) 和[S]都是合法的

(3)假如A 和 B 都是合法的,那麼AB和BA也是合法的

例如以下是合法的括號序列:

()[](())([])()[]()[()]

以下是不合法括號序列的:

([])(([])([()

現在給定一些由'(', ')', '[', ,']'構成的序列 ,請新增儘量少的括號,得到一個合法的括號序列。

輸入描述 Input Description

輸入包括號序列S。含最多100個字元(四種字元: '(', ')', '[' and ']') ,都放在一行,中間沒有其他多餘字元。

輸出描述 Output Description

使括號序列S成為合法序列需要新增最少的括號數量。

樣例輸入 Sample Input
([()
樣例輸出 Sample Output
2
最後一次把不合法的S變為合法的之前可能情況:
1)S形如(S′)或[S′]:
   只需把S′變合法即可。
   f[i,j]= f[i+1,j-1]
2)S形如(S′ 或[S′:
   先把S′變為合法的,右邊加 )或]即可。
   f[i,j]= f[i+1,j]+1

3)S形如   S′)或S′]:
   先把S′化為合法的,左邊加(或 [即可。
   f[i,j]= f[i,j-1]+1
4)把長度大於1的序列SiSi+1…..Sj-1Sj分為兩部分:
   Si...... Sk,Sk+1….. Sj
   分別化為規則序列.
   則:f[i,j]=f[i,k]+f[k+1,j] ;i<=k<=j-1;
上述4種情況取最小值即可。

程式碼如下:

//codevs3657 括號序列 區間DP
//copyright by ametake
#include
#include
#include
using namespace std;

const int maxn=100+10;
const int maxint=0x3f3f3f3f;
char s[100+10];
int f[maxn][maxn];

int main()
{
    scanf("%s",s);
    int n=strlen(s);
    for (int i=0;i

——宣父猶能畏後生,丈夫未可輕年少。