您的位置:首页 > 其它

DP经典应用(三)最长公共子序列LCS问题

2017-04-06 19:54 190 查看

最长公共子序列问题

问题描述:

给定两个字符串 s1,s2,…..sn 和 t1,t2,….tm。求出这两个字符串最长的公共子序列的长度。

样例输入:

4

4

a b c d

b e c d

样例输出:

3

分析:

按照3个步骤:

1.刻画最优解结构特征:

定义dp[i][j]s1,….si 与 t1,…tj 的最长公共子序列长度

2.递归地定义最优解的值:

对于序列s1,….sn 和 t1,…,tj 两个序列的最长公共子序列有三种情况:

(1).当s[i+1] 等于 t[j+1] ,那么在s1…si 和 t1…tj的公共子序列末尾追加上s[i+1]。

(2).s1…si 和 t1…tj+1的公共子序列。

(3).s1…si+1 和 t1…tj 的公共子序列。

那么便有如下递推关系

dp[i+1][j+1] =

max(dp[i][j]+1,dp[i][j+1],dp[i+1][j]) (si+1 = sj+1)

max(dp[i][j+1],dp[i+1][j]) (其他)

-3.计算最优解的值(递推)

代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1000+10;
char s1[maxn],s2[maxn];
int dp[maxn][maxn];//dp[i][j]为s11...s1i和s21....s2j对应的LSC长度

int main()
{
scanf("%s",s1);
scanf("%s",s2);
int m = strlen(s1);
int n = strlen(s2);
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
if(s1[i] == s2[j])
{
dp[i+1][j+1] = dp[i][j] + 1;
}else{
dp[i+1][j+1] = max(dp[i][j+1], dp[i+1][j]);
}
}
}
printf("%d\n",dp[m]
);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: