最长共同子序列 --- DP(动态规划)

题目,就是首先输入两个串的长度,

接着输入两个串

 n = 4

m = 4

s = "abcd"

t = "bcde"

输出:

3 (“bcd”)

就是公共的最长子序列。

解题分析:

对于这种题目,首先要推倒转移方程,那么这里可以先定义二维数组dp[ i ] [ j ]

然后根据串 s  和 t 的长度 i , j来定义方程

s1....si 与 T1,,....Tj 的共同子序列是dp[ i ] [ j ]

这样一来, S1.....Si 与 t1 ... tj的共同子序列之后加上Si + 1,

s1 .... si 与  t1 ...t j + 1的共同子序列,

和 s1....S i +1 与 t1.....t j 的共同子序列的其中之一因此下面公式成立。

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

{

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

       max( dp[ i  ] [ j + 1] + dp [ i + 1] [ j ] ) (除此之外)

}

这个运算的时间复杂度是: O(n * m)

代码如下:

<strong><span style="font-size:18px;">#include <iostream>
#include <cstdio>
#define MAXN 1000
using namespace std;
int n, m;
char s[MAXN], t[MAXN];
int dp[MAXN][MAXN];
int main()
{
		cin>>n>>m;
		for(int i = 0; i < n; i++)
		{
			cin >> s[i];
		}
		for(int i = 0; i < m; i++)
		{
			cin >> t[i];
		}
		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]);
				}
			}
		}
		cout<<dp[n][m]<<endl;
		return 0;
}
</span></strong>

时间: 2024-11-02 15:39:32

最长共同子序列 --- DP(动态规划)的相关文章

nyist oj 36 最长公共子序列 (动态规划基础题)

最长公共子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共子序列. tip:最长公共子序列也称作最长公共子串(不要求连续),英文缩写为LCS(Longest Common Subsequence).其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列. 输入 第一行给出一个整数N(0<N<100)表示待测数据组数 接

最长公共子序列(动态规划)

#include<iostream> #include<vector> #include<iterator> #include<algorithm> #include<string> using namespace std; /* *最长公共子序列(动态规划) */ vector<vector<int>> c;//c[i][j]记录串a[0..i]与串b[0..j]之间的最长公共子序列的长度 vector<vecto

lis(最长上升子序列) dp

lis(最长上升子序列) dp 求序列的lis,子序列可不连续 for(int i=1;i<=N;i++){ scanf("%d",&a[i]); dp[i]=1; } for(int i=2;i<=N;i++){ for(int j=1;j<i;j++){ if(a[j]<a[i]) dp[i]=max(dp[i],dp[j]+1); } } int ans=1; for(int i=1;i<=N;i++){ //注意并不是dp[N]最大,而是要

POJ-2533最长上升子序列(DP+二分)(优化版)

Longest Ordered Subsequence Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 41944   Accepted: 18453 Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given numeric sequence (a1, a2, ...

hdu 1159 Common Subsequence(最长公共子序列 DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1159 Common Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 25416    Accepted Submission(s): 11276 Problem Description A subsequence of

OpenJudge Bailian 2757 最长上升子序列 DP

最长上升子序列 Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u OpenJ_Bailian 2757 Description 一个数的序列 bi,当 b1 < b2 < ... < bS的时候,我们称这个序列是上升的.对于给定的一个序列( a1, a2, ..., aN),我们可以得到一些上升的子序列( ai1, ai2, ..., aiK),这里1 <= i1 <

hdu 1159 common sequence (最长公共子序列 dp)

http://acm.hdu.edu.cn/showproblem.php?pid=1159 题意 : 给出两个字符串 求出最长公共子序列 思路: if(str1[i]==str2[j]) { dp[i][j]=max(dp[i-1][j-1]+1,max(dp[i-1][j],dp[i][j-1])); } else dp[i][j]=max(dp[i-1][j],dp[i][j-1]); #include<cstdio> #include<cstring> #include&l

lcs(最长公共子序列),dp

lcs(最长公共子序列) 求两个序列的lcs的长度,子序列可不连续 dp[i][j]=dp[i-1][j-1]+1(a[i]==b[i]) dp[i][j]=max(dp[i-1][j],dp[i][j-1])(a[i]!=b[i]) memset(dp,0,sizeof(dp)); for(int i=1;i<=n1;i++){ for(int j=1;j<=n2;j++){ if(a[i]==b[j]) dp[i][j]=dp[i-1][j-1]+1; else dp[i][j]=max(

最长公共子序列 DP

算法老师的作业,一道dp基础题,给你两个序列,问你最长公共子序列是什么,比如:(a,b)是(a,c,d,b)的子序列.注意不是最长公共子串,这里的子序列可以不连续. 两个for循环就出来了,每一个dp[i][j]可以从dp[i-1][j-1].dp[i-1][j].dp[i][j-1]三种情况更新过来,取个最大的,然后把路径用123存下来,最后再顺着路径找然后逆序输出就行. sample input: 7 4 A B C B D A B B C D B 7 6 A B C B D A B B D