[dp]最长公共子序列问题
2015-05-25 17:48
211 查看
最长公共子序列问题
给定两个字符串s1s2…sn和t1t2…tn。求出这两个字符串最长的公共子序列的长度.
限制条件:1<=n,m<=1000
输入:
n = 4
m = 4
s = "abcd"
t = "becd"
输出
3 ("bcd")
这个问题是被成为最长公共子序列(LCS)的著名问题。不妨用如下方式定义试试看:
定义:dp[i][j] = s[1]…s[i+1] 和 t[1]…t[j+1]对应的LCS的长度
由此,s[1]…s[i] 和 t[1]…t[j] 的公共子序列末尾追加上
(1)、s[i+1]
(2)、s[1] …s[i] 和 t[1] …t[j+1]的公共子序列
(3)、s[1] …s[i+1]和t[1]…t[j]的公共子序列
三者中的某一个,所以就有如下的递推关系成立:
(1) 当s[i+1] = t[j+1] 时,dp[i+1][j+1] = max(dp[i][j]+1,dp[i][j+1],dp[i+1][j])
(2) 当s[i+1] !=t[j+1] 时,dp[i+1][j+1] = max(dp[i][j+1],dp[i+1][j])
这个递推式可以用O(nm)的复杂度算出来,dp
[m]就是LCS的长度。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 1005;
int n,m;
char s[MAXN],t[MAXN];
int dp[MAXN][MAXN];
int main()
{
while(cin>>n>>m)
{
scanf("%s",s);
scanf("%s",t);
memset(dp,0,sizeof(dp));
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if(s[i] == t[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;
}
给定两个字符串s1s2…sn和t1t2…tn。求出这两个字符串最长的公共子序列的长度.
限制条件:1<=n,m<=1000
输入:
n = 4
m = 4
s = "abcd"
t = "becd"
输出
3 ("bcd")
这个问题是被成为最长公共子序列(LCS)的著名问题。不妨用如下方式定义试试看:
定义:dp[i][j] = s[1]…s[i+1] 和 t[1]…t[j+1]对应的LCS的长度
由此,s[1]…s[i] 和 t[1]…t[j] 的公共子序列末尾追加上
(1)、s[i+1]
(2)、s[1] …s[i] 和 t[1] …t[j+1]的公共子序列
(3)、s[1] …s[i+1]和t[1]…t[j]的公共子序列
三者中的某一个,所以就有如下的递推关系成立:
(1) 当s[i+1] = t[j+1] 时,dp[i+1][j+1] = max(dp[i][j]+1,dp[i][j+1],dp[i+1][j])
(2) 当s[i+1] !=t[j+1] 时,dp[i+1][j+1] = max(dp[i][j+1],dp[i+1][j])
这个递推式可以用O(nm)的复杂度算出来,dp
[m]就是LCS的长度。
j i | 0 | 1(b) | 2(e) | 3(c) | 4(d) |
0 | 0 | 0 | 0 | 0 | 0 |
1(a) | 0 | 0 | 0 | 0 | 0 |
2(b) | 0 | 1 | 1 | 1 | 1 |
3(d) | 0 | 1 | 1 | 2 | 2 |
4(d) | 0 | 1 | 1 | 2 | 3 |
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 1005;
int n,m;
char s[MAXN],t[MAXN];
int dp[MAXN][MAXN];
int main()
{
while(cin>>n>>m)
{
scanf("%s",s);
scanf("%s",t);
memset(dp,0,sizeof(dp));
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if(s[i] == t[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;
}
相关文章推荐
- 最长公共子序列问题 经典DP
- LCS 最长公共子序列(DP经典问题)
- 最长公共子序列的问题 (DP)
- DP经典应用(三)最长公共子序列LCS问题
- DP复习——最长公共子序列 LCS 问题
- DP---LCS 最长公共子序列问题
- DP---LCS 最长公共子序列问题
- 【dp基础课程】矩阵取数问题+最大子段和+最长公共子序列(LCS)【51nod】
- 算法(DP):最长公共子序列问题
- 最长公共子序列问题(LCS)(DP)
- 基于DP的LCS(最长公共子序列)问题
- DP问题之最长公共子序列
- 基于DP的LCS(最长公共子序列)问题
- 最长公共子序列问题—水水的Dp
- NYOJ 36 最长公共子序列 【dp问题】
- xynu 问题 G: [动归基础]最长公共子序列( dp )
- 算法学习之二——用DP和备忘录算法求解最长公共子序列问题
- 公主和王子能在一起多久的问题+dp+最长公共子序列转最长子序列。
- hdu1159 - Common Subsequence (dp 最长公共子序列问题)
- nyoj 36 最长公共子序列 dp问题最长公共子序列 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共