zoukankan      html  css  js  c++  java
  • POJ 2955 Brackets (DP Or 记忆化搜索 总结)

    POJ - 2955 Brackets 

    We give the following inductive definition of a “regular brackets” sequence:

    • the empty sequence is a regular brackets sequence,
    • if s is a regular brackets sequence, then (s) and [s] are regular brackets sequences, and
    • if a and b are regular brackets sequences, then ab is a regular brackets sequence.
    • no other sequence is a regular brackets sequence

    For instance, all of the following character sequences are regular brackets sequences:

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

    while the following character sequences are not:

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

    Given a brackets sequence of characters a1a2 … an, your goal is to find the length of the longest regular brackets sequence that is a subsequence of s. That is, you wish to find the largest m such that for indices i1i2, …, im where 1 ≤ i1 < i2 < … < im ≤ nai1ai2 … aim is a regular brackets sequence.

    Given the initial sequence ([([]])], the longest regular brackets subsequence is [([])].

    Input

    The input test file will contain multiple test cases. Each input test case consists of a single line containing only the characters ()[, and ]; each input test will have length between 1 and 100, inclusive. The end-of-file is marked by a line containing the word “end” and should not be processed.

    Output

    For each input case, the program should print the length of the longest possible regular brackets subsequence on a single line.

    Sample Input
    ((()))
    ()()()
    ([]])
    )[)(
    ([][][)
    end
    Sample Output
    6
    6
    4
    0
    6

    这个好像比那个here更简单一些


    题意:求出互相匹配的括号的总数
    思路:一道区间DP,dp[i][j]存的是i~j区间内匹配最大个数
    网上多数的递推表达式不太懂都是这样的:

    if(s[i]=='('&&s[j]==')'||s[i]=='['&&s[j]==']')
         dp[i][j]=dp[i+1][j-1]+2;
    dp[i][j]=max{dp[i][k]+dp[k+1][j]};



    还是我自己写的好想一些:

     dp[i][j]=max(dp[i][j-1], 2+dp[i][k-1]+dp[k+1][j-1])   i<=k<j    dp[i][j-1]为和谁都不匹配   2+dp[i][k-1]+dp[k+1][j-1]为和k匹配

    不过好像每次看i好一点,我是看的j所在的匹配情况,不过大同小异

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int N=105;
    char s[N];
    int dp[N][N];
    inline bool check(int i,int j){
        return (s[i]=='['&&s[j]==']' || s[i]=='('&&s[j]==')');
    }
    
    int main(){
        while(~scanf("%s",s+1)){
            if(s[1]=='e') break;
            memset(dp,0,sizeof(dp));
            int n=strlen(s+1); ///还能这么测长度,长见识了
            for(int i=n;i>=1;i--)
                for(int j=i+1;j<=n;j++){
                    dp[i][j]=dp[i][j-1]; ///和谁都不匹配
                    for(int k=i;k<j;k++) ///出现匹配
                      if(check(k,j))
                        dp[i][j]=max(dp[i][j],2+dp[i][k-1]+dp[k+1][j-1]);
                }
            printf("%d
    ",dp[1][n]);
        }
    }
    


    记忆化搜索方式

    突然从这道题目里悟出区间的这种DP好想比之前的那种一般的DP还是和用记忆化搜索啊,因为这里涉及到区间了,所以划分成多个重复子问题更适合。

    暂且这么理解吧

    #include <iostream>
    #include <string.h>
    #include <stdio.h>
    #include <algorithm>
    using namespace std;
    const int MAXN=110;
    char str[MAXN];
    int dp[MAXN][MAXN];
    
    bool check(int i,int j){
      return (str[i]=='('&&str[j]==')')||(str[i]=='['&&str[j]==']');
    }
    
    int solve(int i,int j)
    {
        if(dp[i][j]!=-1) return dp[i][j];
        if(j<=i)  return dp[i][j]=0;
        
        dp[i][j]=solve(i+1,j); ///和谁都不匹配情况
        for(int k=i+1;k<=j;k++)   ///和其中一个匹配
            if(check(i,k))
                dp[i][j]=max(dp[i][j],2+solve(i+1,k-1)+solve(k+1,j));
        return dp[i][j];
    }
    
    int main()
    {
        while(scanf("%s",str)==1)
        {
            if(strcmp(str,"end")==0)break;
            memset(dp,-1,sizeof(dp));
            int n=strlen(str);
            printf("%d
    ",solve(0,n-1));
        }
        return 0;
    }
    











  • 相关阅读:
    满血复活
    绝望,绝望、希望
    认真生活的态度
    星期一
    户外穿越
    认真准备
    早点休息
    LeetCode OJ
    LeetCode OJ
    LeetCode OJ
  • 原文地址:https://www.cnblogs.com/zswbky/p/6792901.html
Copyright © 2011-2022 走看看