使用 DP 查找 LCS
Posted
技术标签:
【中文标题】使用 DP 查找 LCS【英文标题】:Finding LCS using DP 【发布时间】:2017-12-16 05:21:43 【问题描述】:我使用动态编程来找到最长的公共子序列 b/w 两个字符串。代码有什么问题。为什么它总是给出答案为0?
#include<bits/stdc++.h>
using namespace std;
int dp[20][20];
void initialize()
for(int i=0;i<20;i++)
for(int j=0;j<20;j++)
dp[i][j]=-1;
int lcs(string a,string b,int m,int n)
if(m==0||n==0)
return 0;
if(dp[m][n]!=-1)
return dp[m][n];
if(a[m-1]==b[n-1])
return dp[m-1][n-1] = 1+lcs(a,b,m-1,n-1);
if(a[m-1]!=b[n-1])
return dp[n-1][m-1]=max(dp[n][m-1]=lcs(a,b,n,m-1),dp[n-1][m]=lcs(a,b,n-1,m));
int main()
string a="AGGTAB",b="GXTXAYB";
cout<<lcs(a,b,a.length(),b.length());
【问题讨论】:
Dynamic Programming: Longest Common Subsequence的可能重复 【参考方案1】:-
您忘记调用 initialize()
第18行,应该是dp[m][n],而不是dp[m-1][n-1]
注释了第 19 行代码,因为不需要 & 让代码与所有编译器兼容
即,某些编译器可能会给出警告:控制到达非空函数的结尾 [-Wreturn-type]
-
在第 20 行进行了一些代码更改,因为您似乎与变量 m 和 n 混淆了。
代码:
#include<bits/stdc++.h>
using namespace std;
int dp[20][20];
void initialize()
for(int i=0;i<20;i++)
for(int j=0;j<20;j++)
dp[i][j]=-1;
int lcs(string a,string b,int m,int n)
if(m==0||n==0)
return 0;
if(dp[m][n]!=-1)
return dp[m][n];
if(a[m-1]==b[n-1])
return dp[m][n] = 1+lcs(a,b,m-1,n-1);
//if(a[m-1]!=b[n-1])
return dp[m][n]=max(lcs(a,b,m-1,n),lcs(a,b,m,n-1));
int main()
string a="AGGTAB",b="GXTXAYB";
initialize();
cout<<lcs(a,b,a.length(),b.length());
输出:
4
【讨论】:
以上是关于使用 DP 查找 LCS的主要内容,如果未能解决你的问题,请参考以下文章
[LCS] nwHJ65 查找两个字符串a,b中的最长公共子串(LCS+KMP+substr暴力)