• POJ 2955 Brackets 【区间DP】


    题目链接

    题意

    给一串包含中括号和小括号的字符串,求其括号匹配正常的顺序(不一定连续)子串中的(最长串)

    分析

    状态

    区间问题的一般处理方法:设dp[i][j]j

    状态转移方程

    1. 如果这个区间两个端点的括号是匹配的,那么它可以是由去掉两端点的串加上2转移而来,比如([])
      dp[i][j]=max(dp[i][j],dp[i+1][j1]+2)
    2. 它也可能是由它的两个串拼在一起而成的,比如()[]
      dp[i][j]=max(dp[i][j],dp[i][i]+dp[i+1][j]dp[i][j1]+dp[j][j])

    初始化

    这题数据量小,可以记忆化搜索,就不用考虑初始化的问题。
    如果递推的话,先全部初始化为零,然后把相邻位置且匹配的区间初始化为2即可。

    DP顺序

    记忆化搜索不用说。递推时,观察状态转移方程,两个端点都在动,然而可以确定的是,状态转移依赖的区间的长度都比待求的小。因此可以以区间长度递增为DP顺序(从长度为3开始)。

    最终解

    自然是dp[0][n]

    AC代码

    //POJ 2955 Brackets
    //AC 2016-5-25 16:20:35
    //DP
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cctype>
    #include <cstdlib>
    #include <cstring>
    #include <vector>
    #include <set>
    #include <string>
    #include <map>
    #include <queue>
    #include <deque>
    #include <list>
    #include <sstream>
    #include <stack>
    using namespace std;
    
    #define cls(x) memset(x,0,sizeof x)
    #define inf(x) memset(x,0x3f,sizeof x)
    #define neg(x) memset(x,-1,sizeof x)
    #define ninf(x) memset(x,0xc0,sizeof x)
    #define st0(x) memset(x,false,sizeof x)
    #define st1(x) memset(x,true,sizeof x)
    #define INF 0x3f3f3f3f
    #define lowbit(x) x&(-x)
    #define bug cout<<"here"<<endl;
    //#define debug
    
    int dp[110][110];
    char seq[110];
    
    bool thesame(int a,int b)
    {
        char &l=seq[a],&r=seq[b];
        if(l=='('&&r==')')
            return 1;
        if(l=='['&&r==']')
            return 1;
        return 0;
    }
    
    int dyna(int a,int b)
    {
        if(dp[a][b]==-1)
        {
            if(a>=b)
                dp[a][b]=0;
            else
            {
                for(int i=0;a+i<b;++i)
                    dp[a][b]=max(dp[a][b],dyna(a,a+i)+dyna(a+i+1,b));
                if(thesame(a,b))
                    dp[a][b]=max(dp[a][b],dyna(a+1,b-1)+2);
            }
        }
        return dp[a][b];
    }
    
    
    int main()
    {
        #ifdef debug
            freopen("E:\Documents\code\input.txt","r",stdin);
            freopen("E:\Documents\code\output.txt","w",stdout);
        #endif
        while(scanf("%s",seq)!=EOF&&seq[0]!='e')
        {
            neg(dp);
            printf("%d
    ",dyna(0,strlen(seq)-1));
        }
        return 0;
    }
    
  • 相关阅读:
    201521123098 《Java程序设计》 第5周学习总结
    201521123098 《Java程序设计》 第4周学习总结
    201521123098 《Java程序设计》第3周学习总结
    Beta阶段Scrum 冲刺博客合集
    项目复审——Alpha阶段
    事后诸葛亮分析
    展示博客
    测试与发布
    Alpha阶段敏捷冲刺总结
    敏捷冲刺七
  • 原文地址:https://www.cnblogs.com/DrCarlluo/p/6580615.html
Copyright © 2020-2023  润新知