POJ2955——Brackets

3107 단어 dp
Brackets
Time Limit: 1000MS
 
Memory Limit: 65536K
Total Submissions: 3341
 
Accepted: 1717
Description
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 ofs. That is, you wish to find the largest m such that for indicesi1, i2, …, im where 1 ≤i1 < i2 < … < im ≤ n, ai1ai2 …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

    Source
    Stanford Local 2004
    또한 매우 고전적인 구간 dp문제입니다. 우리는 dp[i][j]로 i에서 j까지 최대 괄호 일치수를 나타냅니다.
    만약 i번째 괄호가 [i+1, j]에서 일치하지 않는다면 dp[i][j]=dp[i+1][j];
    그렇지 않으면 구간 [i, j]에서 k를 찾아 i와 k를 맞추면 구간은 2단, [i+1, k-1]와 [k+1, j]로 나뉜다.
    그래서 dp[i][j]=max(dp[i+1][j], dp[i+1][k-1]+dp[k+1][j]+2)
    #include <map>  
    #include <set>  
    #include <list>  
    #include <stack>  
    #include <queue>  
    #include <vector>  
    #include <cmath>  
    #include <cstdio>  
    #include <cstring>  
    #include <iostream>  
    #include <algorithm>  
      
    using namespace std;
    
    char str[110];
    int dp[110][110];
    
    int main()
    {
    	while (~scanf("%s", str), str[0] != 'e')
    	{
    		int len = strlen(str);
    		memset (dp, 0, sizeof(dp));
    		for (int i = len - 1; i >= 0; --i)
    		{
    			for (int j = i + 1; j < len; ++j)
    			{
    				dp[i][j] = dp[i + 1][j];
    				for (int k = i + 1; k <= j; ++k)
    				{
    					if ((str[i] == '(' && str[k] == ')') || (str[i] == '[' && str[k] == ']'))
    					{
    						dp[i][j] = max(dp[i][j], dp[i + 1][k - 1] + dp[k + 1][j] + 2);
    					}
    				}
    			}
    		}
    		printf("%d
    ", dp[0][len - 1]); } return 0; }

    좋은 웹페이지 즐겨찾기