给出问题:
据说是一串括号
如果字符串中的左括号和右括号可以正确配对,则平衡。例如,字符串“(())”和“()()”都是平衡的,而字符串“(()(”不是
均衡。
给定长度为 n 的字符串 n 由括号组成,假设您要查找平衡的 S 的最长子序列。使用动态编程,设计一种算法,在 O(n ^ 3)时间内找到 S 的最长平衡子序列。
我的方法:
假设给定字符串:S [1 2 ... n]
有效的子序列可以在S [i]结束,如果S [i] ==')',即S [i]是右括号,并且在S [i]之前存在至少一个未使用的开括号。这可以在O(N)中实现。
#include<iostream>
using namespace std;
int main(){
string s;
cin >> s;
int n = s.length(), o_count = 0, len = 0;
for(int i=0; i<n; ++i){
if(s[i] == '('){
++o_count;
continue;
}
else if(s[i] == ')' && o_count > 0){
++len;
--o_count;
}
}
cout << len << endl;
return 0;
}
我尝试了几个测试用例,似乎工作正常。我在这里错过了什么吗?如果没有,那么我该如何为这个问题设计一个 O(n ^ 3)动态规划解决方案呢?
这是我正在使用的subsequence的定义。
谢谢!
答案 0 :(得分:2)
对于O(n^3)
DP,我觉得这应该有效:
dp[i, j] = longest balanced subsequence in [i .. j]
dp[i, i] = 0
dp[i, i + 1] = 2 if [i, i + 1] == "()", 0 otherwise
dp[i, j] = max{dp[i, k] + dp[k + 1, j] : j > i + 1} in general
这可以与optimal matrix chain multiplication的方式类似地实现。
您的算法对我来说似乎也是正确的,例如看到这个问题:
解决方案与您的解决方案基本相同。
你只是忽略了额外的括号,所以我不明白为什么它不起作用。
答案 1 :(得分:1)
这是Java中的O(n^2)
时间和空间DP解决方案:
public int findLongestBalancedSubsequence(String seq, int n) {
int[][] lengths = new int[n][n];
for (int l = 1; l < n; l++) {
for (int i = 0; i < n - l; i++) {
int j = i + l;
// Ends are balanced.
if (seq.charAt(i) == '(' && seq.charAt(j) == ')') {
// lengths[i, j] = max(lengths[i + 1, j - 1] + 2, lengths[i + 1, j] +
// lengths[i, j - 1] - lengths[i + 1, j - 1])
if (lengths[i + 1][j - 1] + 2 > lengths[i + 1][j] +
lengths[i][j - 1] - lengths[i + 1][j - 1])
lengths[i][j] = lengths[i + 1][j - 1] + 2;
else
lengths[i][j] = lengths[i + 1][j] +
lengths[i][j - 1] - lengths[i + 1][j - 1];
// Ends are not balanced.
} else {
// lengths[i, j] = max(lengths[i + 1, j], lengths[i, j - 1])
if (lengths[i + 1][j] > lengths[i][j - 1])
lengths[i][j] = lengths[i + 1][j];
else
lengths[i][j] = lengths[i][j - 1];
}
}
}
return lengths[0][n - 1];
}