大意:给出一个字符串,求其中最长括号都已匹配好子串(只需知道长度即可)
比较简单的区间dp,
对于f[i][i+1],如果第i个字符与第i+1个匹配则f[i][i+1]=2否则等于0
其他的,f[i][j]=max(f[i][k]+f[k+1][j])(分两段考虑),(形式类似(S1)(S2))
如果第i个字符与第j个字符匹配,则最优方案中两者可能在同一段,
此时f[i][j]=max(f[i][j],f[i+1][j-1]+2)(形式类似(S))
代码如下:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
class Reader {
static BufferedReader reader;
static StringTokenizer tokenizer;
static void init(InputStream input) {
reader = new BufferedReader(new InputStreamReader(input));
tokenizer = new StringTokenizer("");
}
static String next() throws IOException {
while (!tokenizer.hasMoreTokens()) {
tokenizer = new StringTokenizer(reader.readLine());
}
return tokenizer.nextToken();
}
static int nextInt() throws IOException {
return Integer.parseInt(next());
}
}
public class Main {
/**
* @param args
*/
static String str;
static char ch[];
static int len;
static int f[][];
static boolean m[][];
private static boolean match(int a, int b) {
if ((ch[a - 1] == '(') && (ch[b - 1] == ')'))
return true;
if ((ch[a - 1] == '[') && (ch[b - 1] == ']'))
return true;
return false;
}
private static int getmax(int a, int b) {
return a > b ? a : b;
}
private static void deal() {
ch = str.toCharArray();
len = ch.length;
m = new boolean[len + 1][len + 1];
for (int i = 1; i < len; i++)
for (int j = i + 1; j <= len; j++)
m[i][j] = match(i, j);
f = new int[len + 1][len + 1];
for (int i = 1; i < len; i++)
if (m[i][i + 1])
f[i][i + 1] = 2;
for (int i = len - 2; i >= 1; i--) {
for (int j = i + 2; j <= len; j++) {
if (m[i][j])
f[i][j] = f[i + 1][j - 1] + 2;
for (int k = i; k < j; k++)
f[i][j] = getmax(f[i][k] + f[k + 1][j], f[i][j]);
}
}
System.out.println(f[1][len]);
}
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
Reader.init(System.in);
str = Reader.next();
while (!str.equals("end")) {
deal();
str = Reader.next();
}
}
}