HDOJ Common Subsequence 1159【详细分析LCS】

Common Subsequence

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 24753    Accepted Submission(s): 10958


Problem Description
A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = <x1, x2, ..., xm> another sequence Z = <z1, z2, ..., zk> is a subsequence of X if there exists a strictly increasing sequence <i1, i2, ..., ik> of indices of X such that for all j = 1,2,...,k, xij = zj. For example, Z = <a, b, f, c> is a subsequence of X = <a, b, c, f, b, c> with index sequence <1, 2, 4, 6>. Given two sequences X and Y the problem is to find the length of the maximum-length common subsequence of X and Y.
The program input is from a text file. Each data set in the file contains two strings representing the given sequences. The sequences are separated by any number of white spaces. The input data are correct. For each set of data the program prints on the standard output the length of the maximum-length common subsequence from the beginning of a separate line.
 

Sample Input
  
  
abcfbc abfcab programming contest abcd mnp
 

Sample Output
  
  
4 2 0
 

Source
 

Recommend
Ignatius   |   We have carefully selected several similar problems for you:   1087  1176  1058  1069  1257 

题目来源: 点击打开链接

代码模板:
#include<stdio.h>
#include<string.h>
int dp[1000][1000];
int main()
{
	char s1[1000],s2[10000];
	while(~scanf("%s%s",s1,s2))
	{
		memset(dp,0,sizeof(dp));
		int l1,l2,i,j;
		l1=strlen(s1);
		l2=strlen(s2);
		for(i=1;i<=l1;i++)
	    {
	    	for(j=1;j<=l2;j++)
	    	{
	    		if(s1[i-1]==s2[j-1])
	    		dp[i][j]=dp[i-1][j-1]+1;
	    		else
	    		dp[i][j]=dp[i-1][j]>dp[i][j-1]?dp[i-1][j]:dp[i][j-1];
			}
		}
		printf("%d\n",dp[l1][l2]);
	}
	return 0;
}

本人比较笨~~~~~这个道题模板看半天才明白。。。。。。智商不够,痛不欲生啊。。

下面的个人理解仅是一些个人心得,也献给和我一样菜的小牛,欢迎大牛、犬牛、神犇来指出本渣理解不对之处。。。。

先看看下面几幅图片对于连续最长公共子串(最长公共子串要求连续,最长公共子序列不要求)的讲解。。






先大致看下动态规划的一些理论知识。

一、动态规划的基本思想:
动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。这就是动态规划法的基本思路。具体的动态规划算法多种多样,但它们具有相同的填表格式。

二、设计动态规划法的步骤:
1
、找出最优解的性质,并刻画其结构特征;
2
、递归地定义最优值(写出动态规划方程);
3
、以自底向上的方式计算出最优值;(可以看下:杭电2084题数塔,本渣此题的代码:参考代码
4
、根据计算最优值时得到的信息,构造一个最优解。
步骤1-3是动态规划算法的基本步骤。在只需要求出最优值的情形,步骤4可以省略,步骤3中记录的信息也较少;若需要求出问题的一个最优解,则必须执行步骤4,步骤3中记录的信息必须足够多以便构造最优解。

三、动态规划问题的特征:
动态规划算法的有效性依赖于问题本身所具有的两个重要性质:最优子结构性质和子问题重叠性质。
1
、最优子结构:当问题的最优解包含了其子问题的最优解时,称该问题具有最优子结构性质。
2
、重叠子问题:在用递归算法自顶向下解问题时,每次产生的子问题并不总是新问题,有些子问题被反复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只解一次,而后将其解保存在一个表格中,在以后尽可能多地利用这些子问题的解。


此模板代码中二维数组dp,在这里代表的是截止到第i行第j列,也就是s1截止到i个元素,s2截止到第j个元素的最长公共子序列的长度。


第一个测试数据,根据代码算法得



(声明下,其实这里dp[i][j]中,i对应s1第i个元素s1[i-1],j对应s2第j个元素 s2[j-1])
①s1[i-1]!=s2[j-1]的情况,分析截止到第[i-1]个元素的s1与截止到第j个元素的s2最长公共子序列的值dp[i-1][j],再分析截止到第i个元素的s1与截止到j-1个元素的s2的最长公共子序列的值dp[i][j-1]。比较两个值找出最大值,因为s1第i个元素!=s2的第j个元素,所以s1[i-1]与s2[j-1]最长公共子序列就是那两个值的最大值。

②当s1[i-1]==s2[j-1]时,即 s1第i个 元素==s2第j个元素,这种情况下s1与s2的最长公共子序列的长度,等于截止到第i-1个元素的s1与截止到第j-1个元素的s2的最长公共子序列加1,即dp[i][j]的值就等于dp[i-1][j-1]的值加1。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值