区间动态规划-括号匹配(SOJ 1069)

SOJ 1069: Brackets

题意:给出由$(,),[,]$四个字符组成的序列$S$,输出符合要求的括号序列的最大长度。下面是符合要求的括号序列的递归定义:

(1)空序列;

(2)如果$S$是,那么$(S)$和$[S]$也是;

(3)如果$S$和$T$是,那么$ST$也是。

分析:这个问题和矩阵链最优乘法(参考《算法导论》)在分析子结构时有很多相似之处。

定义$dp[i][j]$为子串$S[i..j]$的符合要求的括号序列的最大长度,则

根据(2)我们可得如果$S[i]=S[j]$,则$dp[i][j]=dp[i+1][j-1]+2$;

根据(3)我们可得$dp[i][j]=\max\{dp[i][j],dp[i][k]+dp[k+1][j],i\le k\le j-1\}$.

代码:

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
char s[102];
int dp[102][102];
int main()
{
    int i, j, k;
    int len;
    int delta;
    while (~scanf("%s", s+1) && s[1]!='e')
    {
        memset(dp, 0, sizeof(dp));
        len = strlen(s+1);
        for (delta = 2; delta <= len; delta++)
        {
            for (i = 1; i <= len+1-delta; i++)
            {
                j = i + delta - 1;
                if ((s[i] == '(' && s[j] == ')') || (s[i] == '[' && s[j] == ']'))
                    dp[i][j] = dp[i + 1][j - 1] + 2;
                for (k = i;k<j; k++)
                    dp[i][j] = max(dp[i][j], dp[i][k] + dp[k + 1][j]);
            }
        }
        printf("%d\n", dp[1][len]);
    }
    return 0;
}
View Code

posted on 2019-03-21 14:07  小叶子曰  阅读(461)  评论(0编辑  收藏  举报

导航