zoukankan      html  css  js  c++  java
  • 九度OJ 1337:寻找最长合法括号序列 (DP)

    时间限制:1 秒

    内存限制:32 兆

    特殊判题:

    提交:839

    解决:179

    题目描述:
    给你一个长度为N的,由’(‘和’)’组成的括号序列,你能找出这个序列中最长的合法括号子序列么?合法括号序列的含义便是,在这个序列中,所有的左括号都有唯一的右括号匹配;所有的右括号都有唯一的左括号匹配。例如:((()))()()便是一个长度为10的合法括号序列,而(()))( 则不是。
    需要你求解的是,找出最长的合法括号子序列的长度,同时找出具有这样长度的序列个数。
    输入:
    测试数据包括多个,每个测试数据包含两行:
    第一行为一个整数N,其中N不会超过10^6。
    第二行为一个长度为N的字符串,这个字符串由左括号'('和右括号')'组成。
    输出:
    对应每个测试案例,输出一行,其中包含两个整数,分别代表最长合法括号序列的长度和个数,中间由空格隔开。若没有合法的子序列存在,则返回0 1。
    样例输入:
    6
    (())()
    3
    ))(
    样例输出:
    6 1
    0 1

    思路:

    目前自己还没做出来,先上别人写的代码,过段时间会更新成自己写的代码。

    别人算法的分析:



             红色区域表示已经得到的合法括号序列。

             如上图,分别计算以第i个符号为结尾的最长合法括号序列长度,保存在maxLen[i]中

             在位置pos时,如果该位置为‘(’,显然maxLen[pos]=0;

             如果该位置为')',  我们已经得到了pos-1位置的最长合法括号序列,我们判断以pos-1 位置为结尾的最长合法括号序列的左边位置sympos上的符号是否为'(', 

            如果sympos位置上为‘(’,如图中第2步所示,则以Pos为结尾的最长合法括号序列是以pos-1位置为结果的最长合法括号序列加上sympos上的符号‘(’和pos上的符号‘)’而成,如图第3步。

             接下来还要再加上以sympos-1为结尾的最长合法括号序列,构成最终的合法括号序列。如图第4步。

             另外一个 最长合法括号序列题,不过解决算法相差很大 九度笔记之 1342:寻找最长合法括号序列II


    代码:

    #include <iostream>
    #include <string>
    using namespace std;
    void getMaxLen(std::string &s){
        std::string::size_type len = s.size();
        std::string::size_type pos = 0;
        int *maxLen = new int[len]; //maxLen end at pos
        maxLen[0] = 0;
        int ml = 0;
        int ns = 0;
        for(pos = 1;pos<len;pos++){
            if(s.at(pos)=='(' )
                maxLen[pos]=0;
            else{
                int sympos = pos-1 - maxLen[pos-1];//can't use size_type becase it's unsigned if
                                                   //pos-1 < maxLen[pos-1] sympos will be 0xffffffff
                if(sympos<0 || s.at(sympos)==')'){
                    maxLen[pos]=0;
                }else{
                    maxLen[pos] = maxLen[pos-1]+2;// add () before
                    if(sympos>0){
                        maxLen[pos]+=maxLen[sympos-1];
                    }
      
                    if(maxLen[pos]>ml){
                        ml = maxLen[pos];
                        ns = 1;
                    }else if(maxLen[pos]==ml){
                        ns++;
                    }
                }
            }// else  if(s.at(pos)=='(')
        }//for
        if(ml>0)
            std::cout<<ml<<" "<<ns<<std::endl;
        else
            std::cout<<0<<" "<<1<<std::endl;
    }
      
    void judo(){
        int n;
        std::string s;
        while(std::cin>>n>>s){
            getMaxLen(s);
        }
    }
    void test(){
        std::string s= "())";
        getMaxLen(s);
    }
    int main() {
        //test();
        judo();
        //cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
        return 0;
    }
    /**************************************************************
        Problem: 1337
        User: KES
        Language: C++
        Result: Accepted
        Time:300 ms
        Memory:6452 kb
    ****************************************************************/


             红色区域表示已经得到的合法括号序列。

             如上图,分别计算以第i个符号为结尾的最长合法括号序列长度,保存在maxLen[i]中

             在位置pos时,如果该位置为‘(’,显然maxLen[pos]=0;

             如果该位置为')',  我们已经得到了pos-1位置的最长合法括号序列,我们判断以pos-1 位置为结尾的最长合法括号序列的左边位置sympos上的符号是否为'(', 

            如果sympos位置上为‘(’,如图中第2步所示,则以Pos为结尾的最长合法括号序列是以pos-1位置为结果的最长合法括号序列加上sympos上的符号‘(’和pos上的符号‘)’而成,如图第3步。

             接下来还要再加上以sympos-1为结尾的最长合法括号序列,构成最终的合法括号序列。如图第4步。

             另外一个 最长合法括号序列题,不过解决算法相差很大 九度笔记之 1342:寻找最长合法括号序列II

  • 相关阅读:
    MySQL性能优化(二):优化数据库的设计
    MySQL性能优化(一):优化方式
    PTA 07-图4 哈利·波特的考试 (25分)
    PTA 06-图3 六度空间 (30分)
    PTA 06-图2 Saving James Bond
    PTA 06-图1 列出连通集 (25分)
    PTA 05-树9 Huffman Codes (30分)
    PTA 05-树8 File Transfer (25分)
    PTA 05-树7 堆中的路径 (25分)
    PTA 04-树6 Complete Binary Search Tree (30分)
  • 原文地址:https://www.cnblogs.com/liangrx06/p/5083796.html
Copyright © 2011-2022 走看看