【区间DP/记忆化搜索】Brackets POJ2955

Brackets

  POJ - 2955 

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


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

char ch[105];
int sum[105][105];

int main()
{
	while(~scanf("%s",ch+1))
	{
		if(strcmp(ch+1,"end")==0)
			break;
		
		memset(sum,0,sizeof sum);
		
		int len = strlen(ch + 1);
		
 		for(int l=2;l<=len;l++)  //长度
		{
			for(int s=1;s<=len-l+1;s++)  //起点
			{
				int e=s+l-1;
				if((ch[s]=='('&&ch[e]==')')||(ch[s]=='['&&ch[e]==']'))
				{
					sum[s][e]=max(sum[s][e],sum[s+1][e-1]+2);
				}
				
				for(int k=s;k<e;k++)  //可切割断点k
				{
					sum[s][e]=max(sum[s][e],sum[s][k]+sum[k+1][e]);
				}
				
			}
		}
		
		printf("%d\n",sum[1][len]);
	}
	
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

char ch[105];
int sum[105][105];
int flag[105][105];

int f(int L, int R) {
  if(R <= L) return 0;
  if(flag[L][R]) return sum[L][R];
  
  int ans = 0;
  if(ch[L] == '(' && ch[R] == ')') ans = f(L + 1, R - 1) + 2;
  if(ch[L] == '[' && ch[R] == ']') ans = f(L + 1, R - 1) + 2;
  
  for(int k = L; k < R; k ++) {
	ans = max(ans, f(L, k) + f(k + 1, R));
  }
  
  flag[L][R] = 1;
  return sum[L][R] = ans;
}

int main()
{
	while(~scanf("%s",ch+1))
	{
		if(strcmp(ch+1,"end")==0)
			break;
		memset(sum,0,sizeof sum);
		memset(flag , 0, sizeof flag);
		
		int len = strlen(ch + 1);
		printf("%d\n", f(1, len));
	}
	
	return 0;
}


猜你喜欢

转载自blog.csdn.net/ummmmm/article/details/80425316