fla*_*ash 8 java algorithm data-structures
我试图找到两个非重叠的字符串子序列的最大乘积s,我们将其称为a和b.我想出了下面的代码,但它没有提供正确的输出:
public static int max(String s) {
int[][] dp = new int[s.length()][s.length()];
for (int i = s.length() - 1; i >= 0; i--) {
dp[i][i] = 1;
for (int j = i+1; j < s.length(); j++) {
if (s.charAt(i) == s.charAt(j)) {
dp[i][j] = dp[i+1][j-1] + 2;
} else {
dp[i][j] = Math.max(dp[i+1][j], dp[i][j-1]);
}
}
}
return dp[0][s.length()-1];
}
Run Code Online (Sandbox Code Playgroud)
对于输入字符串"acdapmpomp",我们可以选择a="aca"和b="pmpmp"来获得得分3*5 = 15的最大乘积.但是我的程序给出输出为5.
首先,您应该使用自下而上的方法遍历 dp 表以找出最长回文子序列的长度,然后您可以通过将 dp[i][j] 与 dp[j+1][n-1] 相乘来计算最大乘积:下面给出的是 C++ 代码;
int longestPalindromicSubsequenceProduct(string x){
int n = x.size();
vector<vector<int>> dp(n,vector<int>(n,0));
for(int i=0;i<n;i++){
dp[i][i] = 1;
}
for(int k=1;k<n;k++){
for(int i=0;i<n-k;i++){
int j = i + k;
if(x[i]==x[j]){
dp[i][j] = 2 + dp[i+1][j-1];
} else{
dp[i][j] = max(dp[i][j-1],dp[i+1][j]);
}
}
}
int maxProd = 0;
for(int i=0;i<n;i++){
for(int j=0;j<n-1;j++){
maxProd = max(maxProd,dp[i][j]*dp[j+1][n-1]);
}
}
return maxProd;
}
Run Code Online (Sandbox Code Playgroud)
Mau*_*rry -1
您的算法返回回文的最大长度,而不是两个长度的乘积的最大值。
更新
这是一个可能的解决方案:
public static int max(String s) {
int max = 0;
for (int i = 1; i < s.length()-1; ++i) {
String p1 = bestPalyndrome(s, 0, i);
String p2 = bestPalyndrome(s, i, s.length());
int prod = p1.length()*p2.length();
if (prod > max) {
System.out.println(p1 + " " + p2 + " -> " + prod);
max = prod;
}
}
return max;
}
private static String bestPalyndrome(String s, int start, int end) {
if (start >= end) {
return "";
} else if (end-start == 1) {
return s.substring(start, end);
} else if (s.charAt(start) == s.charAt(end-1)) {
return s.charAt(start) + bestPalyndrome(s, start+1, end-1)
+ s.charAt(end-1);
} else {
String s1 = bestPalyndrome(s, start, end-1);
String s2 = bestPalyndrome(s, start+1, end);
return s2.length() > s1.length() ? s2 : s1;
}
}
Run Code Online (Sandbox Code Playgroud)