`
Simone_chou
  • 浏览: 192870 次
  • 性别: Icon_minigender_2
  • 来自: 广州
社区版块
存档分类
最新评论

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

    博客分类:
  • NYOJ
 
阅读更多


  最长公共子序列

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

    思路:

如图所示为最长公共子序列。(子序列是不连续的,子串是连续的)

 

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

     设有C[i,j]: 保存Xi与Yj的最长公共子序列(LFS)的长度。

 

       

   

   演示过程如图所示,如果Xi,Yi相同,则取对角线的数+1;

   如果Xi,Yi不相同,则对比上面或左边的数,取最大值+1;

   根据下面的演示其实可以发现C[i,j]一直保存着当前(Xi,Yi)的最大子序列长度。

   (1)  当X[i]=Y[j]时, C(i, j)=C(i-1, j-1) 1 。证明很简单。

   (2)  当X[i]!=Y[j]时, 说明此事X[0...i]和Y[0...j]的最长公共子序列中绝对不可能同时含有X[i]和Y[j]。那么公共子序列可能以X[i]结尾,可能以Y[j]结尾,可以末尾都不含有X[i]或Y[j]。

         因此 C(i, j)= MAX{Ci-1 , j), C(i, j-1)}

   

 

   Explain in detail:

   事实上,最长公共子序列问题也有最优子结构性质。

   记:
   Xi = <x1,x2,x3,....xi> 即X序列的前i个字符(1<= i <= m)(前缀)
   Yj = <y1,y2,y3,....yi> 即Y序列的前j个字符(1<= j <= m)(前缀)
   假定Z = <z1,z2,z3,...zk>是LCS(X,Y)中的一个。
   ·若xm = yn(最后一个字符相同),则不难用反正法证明:该字符必是X与Y的任一最长公共子序列Z(设长度为k)的最后一个字符,即有zk = xm = yn,且显然有Zk-1∈LCS(Xm-1,Yn-1),即Z的前缀Zk-1是Xm-1与Yn-1的最长公共子序列。此时,问题化归成求Xm-1与Yn-1的LCS(LCS(X,Y))的长度等于LCS(Xm-1,Yn-1)的长度加1)。
   ·若xm≠yn,则亦不难用反证法证明:要么Z∈LCS(Xm-1, Y),要么Z∈LCS(X , Yn-1)。由于zk≠xm与zk≠yn其中至少有一个必成立,若zk≠xm则有Z∈LCS(Xm-1 , Y);类似的,若zk≠yn 则有Z∈LCS(X , Yn-1)。此时,问题化归成求Xm-1与Y的LCS及X与Yn-1的LCS。LCS(X , Y)的长度为:max{LCS(Xm-1 , Y)的长度, LCS(X , Yn-1)的长度}。
   由于上述当xm≠yn的情况中,求LCS(Xm-1 , Y)的长度与LCS(X , Yn-1)的长度,这两个问题不是相互独立的:两者都需要求LCS(Xm-1,Yn-1)的长度。另外两个序列的LCS中包含了两个序列的前缀的LCS,故问题具有最优子结构性质考虑用动态规划法。

    Wrong:

#include<stdio.h>
#include<string.h>
int main()
{
	int N,i,j;
	int alen,blen;
	char a[1005];
	char b[1005];
	char same[1005][1005];
//手抽这里写错了 应该是int类型……
	scanf("%d",&N);
	while(N--)
	{
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		memset(same,0,sizeof(same));
		scanf("%s",a);
		scanf("%s",b);
		alen=strlen(a);
		blen=strlen(b);
		for(i=1;i<=alen;i++)
		 for(j=1;j<=blen;j++)
		{
			if(a[i-1]==b[j-1]) same[i][j]=same[i-1][j-1]+1;
//这里的字符要-1
			else same[i][j]=(same[i-1][j]>same[i][j-1]?same[i-1][j]:same[i][j-1]);
		}
	    printf("%d\n",same[alen][blen]);
	}
	return 0;
}

    AC:

#include<stdio.h>
#include<string.h>
int main()
{
	int N,i,j;
	int alen,blen;
	char a[1005];
	char b[1005];
	int same[1005][1005];
	scanf("%d",&N);
	while(N--)
	{
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		memset(same,0,sizeof(same));
		scanf("%s",a);
		scanf("%s",b);
		alen=strlen(a);
		blen=strlen(b);
		for(i=1;i<=alen;i++)
		 for(j=1;j<=blen;j++)
		{
			if(a[i-1]==b[j-1]) same[i][j]=same[i-1][j-1]+1;
			else same[i][j]=(same[i-1][j]>same[i][j-1]?same[i-1][j]:same[i][j-1]);
		}
	    printf("%d\n",same[alen][blen]);
	}
	return 0;
}

   总结:

   吸收一下别人的解法。要静下心来慢慢理解。

   http://blog.csdn.net/v_july_v/article/details/6695482

  • 大小: 7.9 KB
  • 大小: 69.2 KB
  • 大小: 13.2 KB
分享到:
评论

相关推荐

    动态规划中的最长公共子序列PPT课件.pptx

    动态规划中的最长公共子序列 动态规划中的最长公共子序列是指给定两个序列 X 和 Y,找到他们的最长公共子序列的长度和该子序列本身。该问题是计算机科学中的一类典型问题,广泛应用于数据压缩、数据挖掘、生物信息...

    最长公共子序列动态规划算法

    ### 最长公共子序列动态规划算法 在计算机科学领域中,**最长公共子序列问题**(Longest Common Subsequence Problem, LCS)是一个经典的算法问题,它主要应用于文本比较、生物信息学中的DNA序列比对等领域。该问题...

    最长公共子序列(动态规划)报告.doc

    【最长公共子序列(动态规划)】是一种经典的算法问题,主要应用于序列比对、文本处理等领域。本实验报告详尽地介绍了如何运用动态规划解决这一问题。 动态规划是一种解决复杂问题的有效方法,它通过将大问题分解为...

    算法设计-最长公共子序列动态规划算法.doc

    算法设计-最长公共子序列动态规划算法 动态规划算法是解决最长公共子序列问题的有效方法。该算法通过建立一个二维数组来存储子问题的解,从而避免了重复计算。 知识点一:最长公共子序列问题 最长公共子序列问题...

    最长公共子序列实验报告

    总之,最长公共子序列问题可以通过动态规划有效地解决,通过构建并填充c和b数组,不仅可以得到LCS的长度,还可以重建LCS本身。这种算法的时间复杂度为O(m * n),显著优于指数级的穷举搜索方法。

    最长公共子序列的动态规划算法

    最长公共子序列(Longest Common Subsequence,LCS)问题是一个经典的计算机科学问题,主要涉及字符串处理和动态规划算法。在本场景中,我们使用C#编程语言来解决这个问题。C#是一种多范式编程语言,广泛应用于开发...

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

    最长公共子序列(Longest Common Subsequence,LCS)是计算机科学中一种经典的字符串问题,主要涉及算法设计与分析,特别是在动态规划领域的应用。在这个问题中,我们需要找到两个或多个字符串之间的最长子序列,这...

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

    在求解最长公共子序列时,我们通常使用二维数组来存储子问题的解,这种方法也被称为动态规划表格。 假设我们有两个字符串 `X` 和 `Y`,长度分别为 `m` 和 `n`,我们可以创建一个大小为 `m+1` by `n+1` 的二维数组 `...

    动态规划算法求最长公共子序列

    动态规划算法求最长公共子序列 动态规划算法是一种常用的算法思想,它通过将复杂的问题分解成多个小问题,并将这些小问题的解组合起来,来解决复杂的问题。在这里,我们使用动态规划算法来求解最长公共子序列问题。...

    最长公共子序列----算法分析之动态规划

    动态规划解决最长公共子序列问题,即寻找两个序列中公共的序列中的最长的那个,结果不唯一,只能输出一个最长公共子序列,并不能生成所有的; 可视化多文档,手动输入两个子序列,显示动态规划算法的解决表格,箭头...

    最长公共子序列问题 动态规划

    最长公共子序列(动态规划) 实验数据:input.txt X={A,B,C,B,D,A,B}; Y={B,D,C,A,B,A} ——要求给出X、Y的最长公共子序列Z,程序运行结束时,将计算结果输出到文件output.txt中。输出文件中包含问题的答案:找不到...

    算法设计与分析实验报告-动态规划寻找最长公共子序列.doc

    实验报告的主题是“算法设计与分析”,关注的是使用动态规划解决最长公共子序列(Longest Common Subsequence, LCS)的问题。动态规划是一种有效的方法,它适用于具有最优子结构和子问题重叠性质的问题。在本实验中...

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

    最长公共子序列(lcs)使用动态规划解决采用c++编写

    最长公共子序列算法试验报告

    【最长公共子序列算法】 最长公共子序列(Longest Common Subsequence, ...在这个实验中,我们学习了如何运用动态规划来找到两个字符串的最长公共子序列,加深了对动态规划思想的理解,并通过实际编程实现了这一过程。

    动态规划实现最长公共子序列

    利用动态规划 实现排序 找到最长公共工子序列

    动态规划方法求解最长公共子序列代码

    动态规划是一种强大的算法思想,广泛应用于计算机科学,特别是在解决最优化问题时,如寻找最长公共子序列(Longest Common Subsequence, LCS)。本主题聚焦于使用动态规划方法求解最长公共子序列问题,并通过C++语言...

    算法实现最长公共子序列问题(动态规划和KR算法)

    总的来说,动态规划和KR算法都是求解最长公共子序列的有效方法,它们各有特点,适用于不同的编程环境和需求。而KMP算法则专注于高效的字符串匹配,虽然与LCS问题不是直接相关,但在字符串处理领域中同样重要。

    实验2. 动态规划法求解最长公共子序列问题与0-1背包问题.doc

    动态规划法求解最长公共子序列问题与0-1背包问题 本实验报告旨在通过动态规划法解决最长公共子序列问题和0-1背包问题,以深入理解动态规划方法的思想、求解策略及步骤。 实验目的 * 理解动态规划方法的核心思想和...

    最长公共子序列c++

    最长公共子序列(Longest Common Subsequence,LCS)是计算机科学中一种经典的字符串问题,主要涉及算法设计和实现,特别是在动态规划领域的应用。在这个问题中,目标是找到两个或多个序列之间的最长子序列,这个子...

Global site tag (gtag.js) - Google Analytics