九度OJ 1337:寻找最长合法括号序列 (DP)
- 题目描述:
-
给你一个长度为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