import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); String s = in.nextLine(); int n = s.length(); int[][] dp = new int[n][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (i == j) { dp[i][j] = 1; } else if (i < j) { dp[i][j] = Integer.MAX_VALUE; } else { dp[i][j] = 0; } } } for (int len = 2; len <= n; len++) { for (int i = 0; i + len <= n; i++) { int j = i + len - 1; int minVal = Integer.MAX_VALUE; for (int k = i; k < j; k++) { if (dp[i][k] != Integer.MAX_VALUE && dp[k + 1][j] != Integer.MAX_VALUE) { int sum = dp[i][k] + dp[k + 1][j]; if (sum < minVal) { minVal = sum; } } } if (match(s.charAt(i), s.charAt(j))) { int inner = (i + 1 <= j - 1) ? dp[i + 1][j - 1] : 0; if (inner < minVal) { minVal = inner; } } dp[i][j] = minVal; } } System.out.println(dp[0][n - 1]); } private static boolean match(char a, char b) { return (a == '(' && b == ')') || (a == '[' && b == ']'); } }
https://www.nowcoder.com/discuss/727521113110073344
思路:
- 初始化:二维数组 dp 被初始化为处理不同长度子串的最小插入数。单个字符初始化为1,空子串初始化为0。
- 处理子串:遍历所有可能的子串长度,从2到整个字符串长度。
- 分割处理:将子串分割成两部分,计算每部分的最小插入数之和,找到最小值。
- 配对处理:检查子串的首尾字符是否可以配对,如果可以,则比较中间子串的插入数,更新最小值。