最长公共子序列的长度(动态规划)

viccode 2012-10-02 05:26:46
给定X = 3, 0, 3, 8, 4, 4
  Y= 4, 3, 8, 3, 0, 4
求X和Y的最长公共子序列的长度。
...全文
386 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
极客剑 2013-11-12
  • 打赏
  • 举报
回复
推荐楼主学习一下 http://onestraw.net/wordpress/tag/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92/
zc850463390zc 2012-10-05
  • 打赏
  • 举报
回复
这是DP入门题。
建议楼主百度一下。。
导出都是
huangxy10 2012-10-04
  • 打赏
  • 举报
回复
DP主要就是一个递推公式。
其实现还是比较简单的,填表法,需要记录解的过程,这样才能在之后找到解。


#include <iostream>
#include <string>
#include <stack>
using namespace std;

/*
DP的核心公式:
if xi = yj:
LCS(xi,yj)=LCS(xi-1,yj-1)+1;
else
LCS(xi,yj)=max(LCS(xi-1,yj),LCS(xi,yj-1)).
*/

int LCS_DP( string x, string y )
{
int xlen=x.size();
int ylen=y.size();
//int *lcs = new int[(xlen+1)*(ylen+1)]();
int **lcs = new int*[xlen+1];
int **path = new int*[xlen+1];

for( int i=0; i<=xlen; i++){
lcs[i] = new int[ylen+1]();
path[i] = new int[ylen+1]();
}

for( int k=1; k<=xlen+ylen;k++){
for( int i=1; i<=xlen; i++){
for( int j=1; j<=k-i&&j<=ylen; j++){
if(x[i-1]==y[j-1]){
lcs[i][j] = lcs[i-1][j-1]+1;
path[i][j] = 1; //1表示两个字符相等
}
else{
int a=lcs[i-1][j];
int b=lcs[i][j-1];
lcs[i][j] = a>b?a:b;
path[i][j] = a>b?2:3; //2表示来自y,3表示来自x
}
}
}
}

stack<char> stk;
for( int i=xlen,j=ylen; i>0&&j>0; )
{
if( path[i][j] == 1 ){
stk.push( x[i-1] );
i--;j--;
}
if( path[i][j] == 2 ){
i--;
}
if( path[i][j] == 3 ){
j--;
}
}

cout <<"The Longest Common Sequence Length: " <<lcs[xlen][ylen]<<endl;
cout <<"The Longest Common Sequence is:"<<endl;
while( !stk.empty() ){
cout << stk.top();
stk.pop();
}

return lcs[xlen][ylen];
}

int main()
{
string a,b;
cout << "Input two string: " <<endl;
cin>> a >> b;
LCS_DP( a, b);
return 0;
}
viccode 2012-10-03
  • 打赏
  • 举报
回复
叫你写算法,你以为?
  • 打赏
  • 举报
回复
递归式是这样:
if xi = yi:
LCS(xi,yi)=LCS(xi-1,yi-1)+1;
else
LCS(xi,yi)=max(LCS(xi-1,yi),LCS(xi,yi-1)).
NULL 2012-10-03
  • 打赏
  • 举报
回复
int len[8][6] = {0}; //记录序列1的 i 和序列2的 j 的最长公共子序列的长度
int flag[8][6] = {0}; //记录在i和j处的选择,为后面输出最长子序列

int LCS()
{
int i, j;

for(i=1; i<m; i++)
{
for(j=1; j<n; j++)
{
if(X[i] == Y[j])
{
len[i][j] = len[i-1][j-1] + 1;
flag[i][j] = 0;
}
else if(len[i-1][j] >= len[i][j-1])
{
len[i][j] = len[i-1][j];
flag[i][j] = 1;
}
else
{
len[i][j] = len[i][j-1];
flag[i][j] = 2;
}
}
}
return len[m-1][n-1];
}

void printLCS(int i, int j)
{
if(i==0 || j==0)
return;
if(flag[i][j] == 0)
{
printLCS(i-1, j-1);
printf("%c ", X[i]);
}
else
{
if(flag[i][j] == 1)
printLCS(i-1, j);
else
printLCS(i, j-1);
}
}

int main()
{
printf("Longest Common Sequence Length: %d\n", LCS());
printLCS(m-1, n-1);
printf("\n");
return 0;
}
DeDeWo 2012-10-02
  • 打赏
  • 举报
回复
这种问题你应该谷歌一下。。。。。很水的,可以搜到答案的问题就不要在这里占贴位了
I'm Daniel Du 2012-10-02
  • 打赏
  • 举报
回复
楼主,我想说,如果自己经过严密的思考,利用搜索工具经过努力尝试仍不能得出答案,那么就带着自己的疑惑询问他人.

33,007

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧