最长共同子序列 --- 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>



你可能感兴趣的:(最长共同子序列 --- DP(动态规划))