pku 2955 Brackets 区间DP

http://poj.org/problem?id=2955

题意:

给定一个只包含'(' , ')' , '[', ']'的字符串,求满足括号匹配的最长子串。

思路:

区间DP,只要找到满足()或者  []  匹配的, dp[i][j] = dp[i +1][j - 1] + 2;然后再枚举i到j之间一点求最大值。

 

记忆化搜索:

//#pragma comment(linker,"/STACK:327680000,327680000")

#include <iostream>

#include <cstdio>

#include <cmath>

#include <vector>

#include <cstring>

#include <algorithm>

#include <string>

#include <set>

#include <functional>

#include <numeric>

#include <sstream>

#include <stack>

#include <map>

#include <queue>



#define CL(arr, val)    memset(arr, val, sizeof(arr))



#define ll long long

#define inf 0x7f7f7f7f

#define lc l,m,rt<<1

#define rc m + 1,r,rt<<1|1

#define pi acos(-1.0)

#define ll long long

#define L(x)    (x) << 1

#define R(x)    (x) << 1 | 1

#define MID(l, r)   (l + r) >> 1

#define Min(x, y)   (x) < (y) ? (x) : (y)

#define Max(x, y)   (x) < (y) ? (y) : (x)

#define E(x)        (1 << (x))

#define iabs(x)     (x) < 0 ? -(x) : (x)

#define OUT(x)  printf("%I64d\n", x)

#define lowbit(x)   (x)&(-x)

#define Read()  freopen("din.txt", "r", stdin)

#define Write() freopen("dout.txt", "w", stdout);





#define N 1007

using namespace std;



int dp[N][N];

bool vt[N][N];

char str[N];

int n;



int DP(int s,int e)

{

    if (s == e) return 0;

    if (vt[s][e]) return dp[s][e];

    if ((str[s] == '(' && str[e] == ')') || (str[s] == '[' && str[e] == ']'))

    dp[s][e] = DP(s + 1,e - 1) + 2;

    for (int t = s + 1; t < e; ++t)

    {

        dp[s][e] = max(dp[s][e],DP(s,t) + DP(t,e));

    }

     vt[s][e] = true;

    return dp[s][e];

}

int main()

{

    //Read();

    while (~scanf("%s",str))

    {

        if (str[0] == 'e') break;

        CL(dp,0); CL(vt,false);

        n = strlen(str);

        int ans = DP(0,n - 1);

        printf("%d\n",ans);

    }

    return 0;



}

  

DP:

//#pragma comment(linker,"/STACK:327680000,327680000")

#include <iostream>

#include <cstdio>

#include <cmath>

#include <vector>

#include <cstring>

#include <algorithm>

#include <string>

#include <set>

#include <functional>

#include <numeric>

#include <sstream>

#include <stack>

#include <map>

#include <queue>



#define CL(arr, val)    memset(arr, val, sizeof(arr))



#define ll long long

#define inf 0x7f7f7f7f

#define lc l,m,rt<<1

#define rc m + 1,r,rt<<1|1

#define pi acos(-1.0)

#define ll long long

#define L(x)    (x) << 1

#define R(x)    (x) << 1 | 1

#define MID(l, r)   (l + r) >> 1

#define Min(x, y)   (x) < (y) ? (x) : (y)

#define Max(x, y)   (x) < (y) ? (y) : (x)

#define E(x)        (1 << (x))

#define iabs(x)     (x) < 0 ? -(x) : (x)

#define OUT(x)  printf("%I64d\n", x)

#define lowbit(x)   (x)&(-x)

#define Read()  freopen("din.txt", "r", stdin)

#define Write() freopen("dout.txt", "w", stdout);





#define N 1007

using namespace std;



int dp[N][N];



char str[N];

int n;





int main()

{

    int i,j,len,t;

   

    while (~scanf("%s",str))

    {

        if (str[0] == 'e') break;

        n = strlen(str);

        CL(dp,0);

        for (len = 1; len < n; ++len)

        {

            for (i = 0; i < n - len; ++i)

            {

                //printf(">>%d %d\n",i,i + len);

                if ((str[i] == '(' && str[i + len] == ')') || (str[i] == '[' && str[i + len] == ']'))

                dp[i][i + len] = dp[i + 1][i + len - 1] + 2;

                for (t = i + 1; t < i + len; ++t)

                {

                    dp[i][i + len] = max(dp[i][i + len],dp[i][t] + dp[t][i + len]);

                }

            }

        }

        printf("%d\n",dp[0][n - 1]);

    }

    return 0;



}

  

 

你可能感兴趣的:(rack)