您的位置:首页 > 其它

动态规划---LCS最长公共子序列

2013-04-02 16:46 183 查看
LCS问题即 longest common subsequence 最长公共子序列问题,也是经典的DP问题。

做这道题目的时候依旧是和做其他DP题目一样,按照步骤,先找到最优子结构,然后确定递归方程,然后就是填表和计算了。

given a sequence X = 〈x1, x2,
..., xm〉, we define the ith prefix of X,
for i = 0, 1, ..., m, as Xi = 〈x1, x2,
..., xi〉. For example, if X =〈A, B, C, B, D, A, B〉,
then X4 = 〈A, B, C, B〉 and X0 is
the empty sequence.

上面是定义一个序列的Xi前缀。

下面给出LCS的最优子结构



由此我们也可以得出下面的递归式



其中数组c[i,j]存的就是序列Xi与Yj的LCS长度。根据这个递归式就可以写代码了

#include<iostream>
using namespace std;

void LCS_Length(char *X,int xlen,char *Y,int ylen,int ch[][7])
{
int i,j;
for(i = 1; i < xlen; i++)
ch[i][0] = 0;

for(j = 0; j < ylen; j++)
ch[0][j] = 0;

for(i = 1; i < xlen; i++)
{
for(j = 1; j < ylen; j++)
{
if(X[i] == Y[j])
ch[i][j] = ch[i - 1][j - 1] + 1;
else if(ch[i - 1][j] >= ch[i][j - 1])
ch[i][j] = ch[i - 1][j];
else
ch[i][j] = ch[i][j - 1];
}
}
}

void Print_LCS(char *X,int ch[][7],int i,int j)
{
if(i == 0 || j == 0)
return;
if(ch[i][j] == (ch[i - 1][j - 1] + 1))
{
Print_LCS(X,ch,i-1,j-1);
cout<<X[i]<<"  ";
}
else if(ch[i][j] == ch[i - 1][j])
Print_LCS(X,ch,i-1,j);
else
Print_LCS(X,ch,i,j-1);
}

int main()
{
char X[] = {'#','B','D','C','B','D','A','B'};
char Y[] = {'#','B','D','C','A','B','A'};
int ch[8][7];
LCS_Length(X,8,Y,7,ch);
Print_LCS(X,ch,7,6);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: