题目描述 Description 
我们用以下规则定义一个合法的括号序列: 
(1)空序列是合法的 
(2)假如
(3)假如
例如以下是一些合法的括号序列: 
以下是一些不合法括号序列的: 
现在给定一些由
输入描述 Input Description 
输入包括号序列
输出描述 Output Description 
使括号序列S成为合法序列需要添加最少的括号数量。
样例输入 Sample Input 
样例输出 Sample Output 
2
数据范围及提示 Data Size & Hint 
【样例说明】 
最少添加2个括号可以得到合法的序列:
【数据范围】 
题解 
又是序列的题目。先一看不能顺着推,再一看不能倒着推,所以想到区间dp。以
设某段序列为
若
若
同理,若
无论
Code
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 110;
const int oo = 0x3f3f3f;
char ch[maxn];
int f[maxn][maxn], n;
void init()
{
    scanf("%s", &ch);
    n = strlen(ch);
    for(int i = 1; i <= n; ++i) f[i][i] = 1;
}
void work()
{
    for(int p = 1; p < n; ++p) for(int i = 1; i <= n - p; ++i)
    {
        int j = p + i;
        f[i][j] = oo;
        if((ch[i - 1] == ‘(‘ && ch[j - 1] == ‘)‘) || (ch[i - 1] == ‘[‘ && ch[j - 1] == ‘]‘))
            f[i][j] = f[i + 1][j - 1];
        if(ch[i - 1] == ‘(‘ || ch[i - 1] == ‘[‘) f[i][j] = min(f[i][j], f[i][j - 1] + 1);
        if(ch[j - 1] == ‘)‘ || ch[j - 1] == ‘]‘) f[i][j] = min(f[i][j], f[i + 1][j] + 1);
        for(int k = i; k < j; ++k) f[i][j] = min(f[i][j], f[i][k] + f[k + 1][j]);
    }
    printf("%d", f[1][n]);
}
int main()
{
    init();
    work();
    return 0; 
}原文:http://blog.csdn.net/t14t41t/article/details/45935215