POJ1458---最长公共子序列(LCS)模板

#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
using namespace std;

char s1[1000],s2[1000];
int dp[1000][1000];
int main()
{
    while (~scanf("%s %s",s1+1,s2+1))
    {
        int len1 = strlen(s1+1);
        int len2 = strlen(s2+1);
        for (int i = 1;i <= len1; i++)
          for (int j = 1;j <= len2; j++)
          {
              if (s1[i] == s2[j])
                dp[i][j] = dp[i-1][j-1]+1;
              else
                dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
          }
        printf("%d\n",dp[len1][len2]);
        memset(dp,0,sizeof(dp));
        memset(s1,0,sizeof(s1));
        memset(s2,0,sizeof(s2));
    }
}

1、dp

经常会遇到复杂问题不能简单地分解成几个子问题,而会分解出一系列的子问题。简单地采用把大问题分解成子问题,并综合子问题的解导出大问题的解的方法,问题求解耗时会按问题规模呈幂级数增加。

为了节约重复求相同子问题的时间,引入一个数组,不管它们是否对最终解有用,把所有子问题的解存于该数组中,这就是动态规划法所采用的基本方法。


2、求解LCS

引进一个二维数组c[][],用c[i][j]记录X[i]与Y[j] 的LCS 的长度,b[i][j]记录c[i][j]是通过哪一个子问题的值求得的,以决定搜索的方向(如果需要记录路径)。

我们是自底向上进行递推计算,那么在计算c[i,j]之前,c[i-1][j-1],c[i-1][j]与c[i][j-1]均已计算出来。此时我们根据X[i] = Y[j]还是X[i] != Y[j],就可以计算出c[i][j]。

问题的递归式写成:

这里写图片描述

回溯输出最长公共子序列的过程:

这里写图片描述


猜你喜欢

转载自blog.csdn.net/sugarbliss/article/details/80708360