0
点赞
收藏
分享

微信扫一扫

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


问题 : 给定2个序列X={x1,x2,…,xm}和 Y={y1,y2,…,yn},找出X和Y的最长公共子序列。

动态规划的基本思想:如果能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,就可以避免大量重复计算,从而得到多项式时间算法。

动态规划的基本步骤:

1、找出最优解的性质,并刻画其结构特征。
2、递归地定义最优值。
3、以自底向上的方式计算最优值。

4、根据计算最优值时得到的信息,构造最优解。

此题递归关系:

 c[i][j] =  0                                 ;         i = j = 0;

          =  c[i - 1][j - 1], x[i] = y[j];         i, j > 0, x[i] = y[j];

          = max{ c[i][j - 1], c[i - 1][j] };     i, j > 0; x[i] != y[j]

代码:

#include<bits/stdc++.h>
using namespace std;
char x[1020], y[1020], z[1020];
int c[1020][1020], b[1020][1020];
int m, n;
void LCSLength()
{
    memset(c, 0, sizeof(c));
    memset(b, 0, sizeof(b));
    for(int i = 1; i <= m; ++i)
    {
        for(int j = 1; j <= n; ++j)
        {
            if(x[i] == y[j])
            {
                c[i][j] = c[i - 1][j - 1] + 1;
                b[i][j] = 1;
            }
            else if(c[i - 1][j] >= c[i][j - 1])
            {
                c[i][j] = c[i - 1][j];
                b[i][j] = 2;
            }
            else
            {
                 c[i][j] = c[i][j - 1];
                 b[i][j] = 3;
            }
        }
    }
}
void LCS(int i, int j)
{
   if(i == 0 || j == 0)
        return ;
   if(b[i][j] == 1)
   {
       LCS(i - 1, j - 1);
       cout << x[i];
   }
   else if(b[i][i] == 2)
   {
       LCS(i - 1, j);
   }
   else
   {
       LCS(i, j - 1);
   }
}
void Input()
{
    gets(x);
    gets(y);
    m = strlen(x);
    n = strlen(y);
    strcpy(x + 1, x);//为了方便,0号位置不放元素
    strcpy(y + 1, y);
}
int main()
{
  Input();
  LCSLength();
  LCS(m, n);
}



举报

相关推荐

0 条评论