DP3_最长公共子序列

 1 using System;
 2 namespace ConsoleApplication2
 3 {
 4     public class Program
 5     {
 6         static int[,] martix;
 7
 8         static string str1 = "cnblogs";
 9         static string str2 = "belong";
10
11         static void Main(string[] args)
12         {
13             martix = new int[str1.Length + 1, str2.Length + 1];
14
15             LCS(str1, str2);
16
17             //只要拿出矩阵最后一个位置的数字即可
18             Console.WriteLine("当前最大公共子序列的长度为:{0}", martix[str1.Length, str2.Length]);
19
20             Console.Read();
21         }
22
23         static void LCS(string str1, string str2)
24         {
25             //初始化边界,过滤掉0的情况
26             for (int i = 0; i <= str1.Length; i++)
27                 martix[i, 0] = 0;
28
29             for (int j = 0; j <= str2.Length; j++)
30                 martix[0, j] = 0;
31
32             //填充矩阵
33             for (int i = 1; i <= str1.Length; i++)
34             {
35                 for (int j = 1; j <= str2.Length; j++)
36                 {
37                     //相等的情况
38                     if (str1[i - 1] == str2[j - 1])
39                     {
40                         martix[i, j] = martix[i - 1, j - 1] + 1;
41                     }
42                     else
43                     {
44                         //比较“左边”和“上边“,根据其max来填充
45                         if (martix[i - 1, j] >= martix[i, j - 1])
46                             martix[i, j] = martix[i - 1, j];
47                         else
48                             martix[i, j] = martix[i, j - 1];
49                     }
50                 }
51             }
52         }
53     }
54 }

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 int MAX(int a, int b)
 6 {
 7     return a>b?a:b;
 8 }
 9 int f(char* x, char* y)
10 {
11     if(strlen(x)==0) return 0;
12     if(strlen(y)==0) return 0;
13     if(*x == *y) return f(x+1,y+1)+1;
14     return  MAX(f(x,y+1),f(x+1,y));
15 }
16 int main()
17 {
18     printf("%d\n", f("ac","abcd")); //2
19     printf("%d\n", f("acebbcde1133","xya33bc11de")); //5
20     return 0;
21 }

概念:

举个例子,cnblogs这个字符串中子序列有多少个呢?很显然有27个,比如其中的cb,cgs等等都是其子序列,我们可以看出

子序列不见得一定是连续的,连续的那是子串。

分析:

既然是经典的题目肯定是有优化空间的,并且解题方式是有固定流程的,这里我们采用的是矩阵实现,也就是二维数组。

第一步:先计算最长公共子序列的长度。

第二步:根据长度,然后通过回溯求出最长公共子序列。

现有两个序列X={x1,x2,x3,...xi},Y={y1,y2,y3,....,yi},

设一个C[i,j]: 保存Xi与Yj的LCS的长度。

动态规划的一个重要性质特点就是解决“子问题重叠”的场景,可以有效的避免重复计算,根据上面的公式其实可以发现C[i,j]一直保存着当前(Xi,Yi)的最大子序列长度

时间: 2024-10-14 11:40:40

DP3_最长公共子序列的相关文章

最长公共子序列的代码实现

关于最长公共子序列(LCS)的相关知识,http://blog.csdn.net/liufeng_king/article/details/8500084 这篇文章讲的比较好,在此暂时不再详说. 以下是我代码实现两种方式:递归+递推: 1 #include <bits/stdc++.h> 2 using namespace std; 3 int A[100]; 4 int B[100]; 5 6 //int B[]={2,3,5,6,9,8,4}; 7 int d[100][100]={0};

NYOJ 36 &amp;&amp;HDU 1159 最长公共子序列(经典)

链接:click here 题意:tip:最长公共子序列也称作最长公共子串(不要求连续),英文缩写为LCS(Longest Common Subsequence).其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列. 输入 第一行给出一个整数N(0<N<100)表示待测数据组数 接下来每组数据两行,分别为待测的两组字符串.每个字符串长度不大于1000. 输出 每组测试数据输出一个整数,表示最长公共子序列长度.每组

poj1159 Palindrome(最长公共子序列)

Palindrome Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 52966   Accepted: 18271 Description A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You are to write a

最长公共子序列(LCS)问题

最长公共子串(Longest Common Substirng)和最长公共子序列(Longest Common Subsequence,LCS)的区别为:子串是串的一个连续的部分,子序列则是从不改变序列的顺序,而从序列中去掉任意的元素而获得新的序列:也就是说,子串中字符的位置必须是连续的,子序列则可以不必连续. 1.序列str1和序列str2 ·长度分别为m和n: ·创建1个二维数组L[m.n]: ·初始化L数组内容为0 ·m和n分别从0开始,m++,n++循环: - 如果str1[m] ==

Longest Common Substring(最长公共子序列)

Longest Common Substring Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 37 Accepted Submission(s): 28   Problem Description Given two strings, you have to tell the length of the Longest Common Su

最长公共子序列针对小字符集的算法

一般对于两个字符串,长度分别为n和m,其时间复杂度为O(nm). 但是针对小字符集的情况,可以把复杂度降低到O(n^2),其中n为两个字符串较短的长度.这种方法对于两个字符串长度相差很大的情况比O(nm)要优化很多. 就假设所有的字符都是小写字母,这样就符合小字符集的前提了.设较短的字符串为S1,较长的字符串为S2.字符串下标从1开始. S2字符串每个位置右边第一个字符是可以通过O(km)预处理得到的.其中k为小字符集的字符个数,m为较长的那个字符串的长度. 用next[i][j]表示S2[i]

动态规划-最长公共子序列

(1).问题描述:给出2个序列,x是从1到m,y是从1到n,找出x和y的最长公共子序列? x:A B C B D A B y:B D C A B A 则:最长公共子序列长度为4,BDAB BCAB BCBA均为LCS(最长公共子序列): 模型实现图: (2).问题解决 代码实现了最长公共子序列的长度 #include<stdio.h> #define N    10 int LCS(int *a, int count1, int *b, int count2); int LCS(int *a,

POJ 1458 Common Subsequence 最长公共子序列

题目大意:求两个字符串的最长公共子序列 题目思路:dp[i][j] 表示第一个字符串前i位 和 第二个字符串前j位的最长公共子序列 #include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> #include<iostream> #include<algorithm> #define INF 0x3f3f3f3f #define MAXSIZE 10

最长公共子序列练习

最长公共子串(Longest Common Substirng)和最长公共子序列(Longest Common Subsequence,LCS)的区别为:子串是串的一个连续的部分,子序列则是从不改变序列的顺序,而从序列中去掉任意的元素而获得新的序列:也就是 说,子串中字符的位置必须是连续的,子序列则可以不必连续.