【发布时间】:2014-07-23 02:21:35
【问题描述】:
给定两个长度为 x1 的字符串字符串 X 和长度为 y1 的字符串 Y,找出两个字符串中从左到右(但不一定在连续块中)出现的最长字符序列。
例如,如果 X = ABCBDAB 且 Y = BDCABA,则 LCS(X,Y) = {"BCBA","BDAB","BCAB"} 且 LCSlength 为 4。
我使用了这个问题的标准解决方案:
if(X[i]=Y[j]) :1+LCS(i+1,j+1)
if(X[i]!=Y[j]) :LCS(i,j+1) or LCS(i+1,j), whichever is greater
然后我使用了记忆,使它成为一个标准的 DP 问题。
#include<iostream>
#include<string>
using namespace std;
int LCS[1024][1024];
int LCSlen(string &x, int x1, string &y, int y1){
for(int i = 0; i <= x1; i++)
LCS[i][y1] = 0;
for(int j = 0; j <= y1; j++)
LCS[x1][j] = 0;
for(int i = x1 - 1; i >= 0; i--){
for(int j = y1 - 1; j >= 0; j--){
LCS[i][j] = LCS[i+1][j+1];
if(x[i] == y[j])
LCS[i][j]++;
if(LCS[i][j+1] > LCS[i][j])
LCS[i][j] = LCS[i][j+1];
if(LCS[i+1][j] > LCS[i][j])
LCS[i][j] = LCS[i+1][j];
}
}
return LCS[0][0];
}
int main()
{
string x;
string y;
cin >> x >> y;
int x1 = x.length() , y1 = y.length();
int ans = LCSlen( x, x1, y, y1);
cout << ans << endl;
return 0;
}
正在运行 here,我在 SPOJ 中使用的这个解决方案,我遇到了超出时间限制和/或运行时错误。
目前仅接受 14 个用户解决方案。有没有更聪明的技巧来降低这个问题的时间复杂度?
【问题讨论】:
-
请正确格式化您的代码以使其可读。
-
@KonradRudolph 我应该添加更多空格吗?我是一个新程序员,所以对格式不太了解。
-
@swapedoc 每个嵌套块都应该有自己的嵌套级别,这是一个普遍的共识。此外,中缀运算符通常应该始终被单个空格包围。逻辑上独立的代码块应该用一个空行分开。这是人们同意的最低限度。其余的主要是口味问题。
-
@Brian 该链接无法从我的位置访问,我有假期,所以我在家,无法使用机构登录。您能否详细说明它的要点或给我发送其他链接阅读论文?
-
@Brian 这是收费的。 at ResearchGate 提供预览版,但他们不提供下载(至少非会员不提供)。
标签: c++ optimization dynamic-programming