nyoj 36 最长公共子序列
来源:互联网 发布:什么是java工程师 编辑:程序博客网 时间:2024/05/16 06:04
动态规划很神奇,在网上看到一位大牛对该类问题的分析,很透彻,转过来吧:
最长公共子序列是一个十分实用的问题,它可以描述两段文字之间的“相似度”,即它们的雷同程度,从而能够用来辨别抄袭。对一段文字进行修改之后,计算改动前后文字的最长公共子序列,将除此子序列外的部分提取出来,这种方法判断修改的部分,往往十分准确。简而言之,百度知道、百度百科都用得上。
算法
动态规划的一个计算两个序列的最长公共子序列的方法如下:
以两个序列 X、Y 为例子:
设有二维数组 f[i,j] 表示 X 的 i 位和 Y 的 j 位之前的最长公共子序列的长度,则有:
f[1][1] = same(1,1);
f[i,j] = max{f[i-1][j -1] + same(i,j),f[i-1,j],f[i,j-1]}
其中,same(a,b)当 X 的第 a 位与 Y 的第 b 位完全相同时为“1”,否则为“0”。
此时,f[j]中最大的数便是 X 和 Y 的最长公共子序列的长度,依据该数组回溯,便可找出最长公共子序列。
该算法的空间、时间复杂度均为O(n^2),经过优化后,空间复杂度可为O(n)。
动态规划法
经常会遇到复杂问题不能简单地分解成几个子问题,而会分解出一系列的子问题。简单地采用把大问题分解成子问题,并综合子问题的解导出大问题的解的方法,问题求解耗时会按问题规模呈幂级数增加。
为了节约重复求相同子问题的时间,引入一个数组,不管它们是否对最终解有用,把所有子问题的解存于该数组中,这就是动态规划法所采用的基本方法。
考虑最长公共子序列问题如何分解成子问题,设A=“a0,a1,…,am-1”,B=“b0,b1,…,bn-1”,并Z=“z0,z1,…,zk-1”为它们的最长公共子序列。不难证明有以下性质:
(1) 如果am-1=bn-1,则zk-1=am-1=bn-1,且“z0,z1,…,zk-2”是“a0,a1,…,am-2”和“b0,b1,…,bn-2”的一个最长公共子序列;(肯定是,因为最后一个若相等,则该字符必在LCS中)
(2) 如果am-1!=bn-1,则若zk-1!=am-1,蕴涵“z0,z1,…,zk-1”是“a0,a1,…,am-2”和“b0,b1,…,bn-1”的一个最长公共子序列;
(3) 如果am-1!=bn-1,则若zk-1!=bn-1,蕴涵“z0,z1,…,zk-1”是“a0,a1,…,am-1”和“b0,b1,…,bn-2”的一个最长公共子序列。
这样,在找A和B的公共子序列时,如有am-1=bn-1,则进一步解决一个子问题,找“a0,a1,…,am-2”和“b0,b1,…,bm-2”的一个最长公共子序列;如果am-1!=bn-1,则要解决两个子问题,找出“a0,a1,…,am-2”和“b0,b1,…,bn-1”的一个最长公共子序列和找出“a0,a1,…,am-1”和“b0,b1,…,bn-2”的一个最长公共子序列,再取两者中较长者作为A和B的最长公共子序列。
题目链接点击打开链接
AC代码:
#include<iostream>#include<string>#include<cstring>const int INF=1005;using namespace std;int _dp[INF][INF];string s1,s2;void dp(){ memset(_dp,0,sizeof(_dp)); for(int i=0;i<s1.length();i++) for(int j=0;j<s2.length();j++) { if(s1[i]==s2[j]) _dp[i+1][j+1]=_dp[i][j]+1; else _dp[i+1][j+1]=_dp[i+1][j]>_dp[i][j+1]?_dp[i+1][j]:_dp[i][j+1]; }}int main(){ int t; cin>>t; while(t--) { cin>>s1>>s2; dp(); cout<<_dp[s1.length()][s2.length()]<<endl; } return 0;}
- nyoj 36 最长公共子序列
- NYOJ 36 最长公共子序列 dp
- NYOJ-36:最长公共子序列
- nyoj 36 最长公共子序列
- nyoj-36-最长公共子序列
- NYOJ-36 最长公共子序列 AC
- NYOJ 36 最长公共子序列
- 最长公共子序列(nyoj 36)
- NYOJ 36 最长公共子序列
- NYOJ 36 最长公共子序列
- NYOJ 36 最长公共子序列
- nyoj 36 最长公共子序列
- NYOJ 36 最长公共子序列
- nyoj 36 最长公共子序列 【DP】
- 最长公共子序列(NYOJ 36)
- nyoj 36 最长公共子序列
- NYOJ 36--最长公共子序列【LCS】
- NYOJ 36 最长公共子序列
- 8 款精美的 jQuery/CSS3 菜单特效
- ALSA and TinyAlsa
- 黑马程序员c#学习15
- SQL Server 触发器
- java方法的参数传递其二
- nyoj 36 最长公共子序列
- 二叉树链表C++实现
- 黑马程序员c#学习16
- Windows socket之IOCP实例----IOCP开发驾照理论考试系统
- 公司面试经验-前篇
- linux中文输入法的实现
- 启动分析
- HTTP 头部详细解释
- Activiti - 新一代的开源 BPM 引擎