[dp]最长公共子序列问题
来源:互联网 发布:期现套利软件 编辑:程序博客网 时间:2024/06/06 21:41
最长公共子序列问题
给定两个字符串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[n][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<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[n][m]); } return 0;}
0 0
- 最长公共子序列问题 经典DP
- [dp]最长公共子序列问题
- DP---LCS 最长公共子序列问题
- 最长公共子序列--DP
- DP---最长公共子序列
- 最长公共子序列dp
- DP 最长公共子序列
- DP 最长公共子序列
- 最长公共子序列-DP
- 【DP】最长公共子序列。
- 最长公共子序列 DP
- DP--最长公共子序列
- dp最长公共子序列
- dp 最长公共子序列
- DP最长公共子序列
- 最长公共子序列-dp
- dp--最长公共子序列
- 最长公共子序列<DP>
- Python正则及re模块
- 微软100题(21)1到n找出所有的和为m的组合
- 搞清楚脚本中这些函数的调用规律
- Android标题栏和状态栏的隐藏功能设置方法
- Linux运行级别
- [dp]最长公共子序列问题
- boost::bind
- 欢迎使用CSDN-markdown编辑器
- C#.net实现密码加密算法
- 第十二周项目4——(4)
- python-Json模块【解析Json】
- jquery刷新页面 页面跳转 js常用函数
- 给IT新人的15点建议:苦逼程序员的辛酸反省与总结
- android:windowSoftInputMode属性详解