准备NOIP2017 最长公共子序列(模版)
例如:
对于一个长度为n的序列,它一共有2^n 个子序列,有(2^n – 1)个非空子序列。
仍然用序列1,3,5,4,2,6,8,7和序列1,4,8,6,7,5
1,4,6,7
请注意: 最长公共子序列不唯一。
请大家用集合的观点来理解这些概念,子序列、公共子序列以及最长公共子序列都不唯一,所以我们通常说一个最长公共子序列,但显然最长公共子序列的长度是一定的。
最长公共子序列问题就是求序列A= a1,a2,……an, 和B = b1,b2,……bm,的一个最长公共子序列。
你首先能想到的恐怕是暴力枚举?那我们先来看看:序列A有 2^n 个子序列,序列B有 2^m 个子序列,如果任意两个子序列一一比较,比较的子序列高达 2^(n+m) 对,这还没有算具体比较的复杂度。
吓着了吧?怎么办?试试使用动态规划算法!
可是,我们事先并不知道t,由定义,我们取最大的一个,因此这种情况下,有LCS(x,y) = max(LCS(x – 1, y) , LCS(x, y – 1))。
看看目前我们已经得到了什么结论:
LCS(x,y) =
(1) LCS(x - 1,y - 1) + 1 如果Ax = By
(2) max(LCS(x – 1, y) , LCS(x, y – 1)) 如果Ax ≠ By
这时一个显然的递推式,光有递推可不行,初值是什么呢?
(1) LCS(x - 1,y - 1) + 1 如果Ax = By
(2) max(LCS(x – 1, y) , LCS(x, y – 1)) 如果Ax ≠ By
(3) 0 如果x = 0或者y = 0
到此我们求出了计算最长公共子序列长度的递推公式。我们实际上计算了一个(n + 1)行(m + 1)列的表格(行是0..n,列是0..m),也就这个二维度数组LCS(,)。
输入序列A, B长度分别为n,m,计算二维表 LCS(int,int):
for x = 0 to n do
for y = 0 to m do
if (x == 0 || y == 0) then
LCS(x, y) = 0
else if (Ax == By) then
LCS(x, y) = LCS(x - 1,y - 1) + 1
else
LCS(x, y) = ) max(LCS(x – 1, y) , LCS(x, y – 1))
endif
endfor
endfor
现在问题来了,我们如何得到一个最长公共子序列而仅仅不是简单的长度呢?其实我们离真正的答案只有一步之遥!
这对应L(x,y) = L(x,- 1 y- 1)末尾接上Ax
这对应L(x,y)= L(x – 1, y)
(2.2) LCS(x, y – 1) 如果Ax ≠ By且LCS(x – 1, y) <LCS(x, y – 1)
这对应L(x,y) = L(x, y – 1)
这对应L(x,y)=空序列
神奇吧?又一个类似的递推公式。可见我们在计算长度LCS(x,y)的时候只要多记录一些信息,就可以利用这些信息恢复出一个最长公共子序列来。就好比我们在迷宫里走路,走到每个位置的时候记录下我们时从哪个方向来的,就可以从终点回到起点一样。
今天对LCS的讲解就到这里,聪明的你是不是已经蠢蠢欲动要AC问题啦? 心动不如行动,赶快吧。
最后,我们来提供输入输出数据,由你来写一段程序,实现这个算法,只有写出了正确的程序,才能继续后面的课程。
第1行:字符串A
第2行:字符串B
(A,B的长度 <= 1000)
输出最长的子序列,如果有多个,随意输出1个。
abcicba
abdkscab
abca
代码
#include<iostream>
#include<cstring>
#include<string> using namespace std; string ans[],a,b;
int w,i,j,dp[][];
int main()
{
cin>>a>>b;
for(i=;i<=a.length() ;++i)
{
for(j=;j<=b.length() ;++j)
{
if(a[i-]==b[j-]) dp[i][j]=dp[i-][j-]+;
else {
if(dp[i][j-]>=dp[i-][j])
dp[i][j]=dp[i][j-];
else dp[i][j]=dp[i-][j];
}
}
}
for(i=a.length(),j=b.length();i>=&&j>=;)
{
if(a[i-]==b[j-])
{
ans[w++]=a[i-];
i--;
j--;
}
else {
if(dp[i][j-]>dp[i-][j])
{
j--;
}
else i--;
}
}
for(j=w-;j>=;--j)
cout<<ans[j];
cout<<endl;
return ;
}
(来源于51nod教程)。
准备NOIP2017 最长公共子序列(模版)的更多相关文章
- hunnu 11313 无重复元素序列的最长公共子序列转化成最长递增子序列 求法及证明
题目:http://acm.hunnu.edu.cn/online/?action=problem&type=show&id=11313 湖师大的比赛,见我的另一篇水题题解,这里要说的 ...
- UVA10100:Longest Match(最长公共子序列)&&HDU1458Common Subsequence ( LCS)
题目链接:http://blog.csdn.net/u014361775/article/details/42873875 题目解析: 给定两行字符串序列,输出它们之间最大公共子单词的个数 对于给的两 ...
- 用python实现最长公共子序列算法(找到所有最长公共子串)
软件安全的一个小实验,正好复习一下LCS的写法. 实现LCS的算法和算法导论上的方式基本一致,都是先建好两个表,一个存储在(i,j)处当前最长公共子序列长度,另一个存储在(i,j)处的回溯方向. 相对 ...
- 动态规划之最长公共子序列(LCS)
转自:http://segmentfault.com/blog/exploring/ LCS 问题描述 定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 ...
- [Data Structure] LCSs——最长公共子序列和最长公共子串
1. 什么是 LCSs? 什么是 LCSs? 好多博友看到这几个字母可能比较困惑,因为这是我自己对两个常见问题的统称,它们分别为最长公共子序列问题(Longest-Common-Subsequence ...
- 动态规划求最长公共子序列(Longest Common Subsequence, LCS)
1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...
- LintCode 77: 最长公共子序列
public class Solution { /** * @param A, B: Two string. * @return: the length of the longest common s ...
- 删除部分字符使其变成回文串问题——最长公共子序列(LCS)问题
先要搞明白:最长公共子串和最长公共子序列的区别. 最长公共子串(Longest Common Substirng):连续 最长公共子序列(Longest Common Subsequence,L ...
- LCS(Longest Common Subsequence 最长公共子序列)
最长公共子序列 英文缩写为LCS(Longest Common Subsequence).其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已 ...
随机推荐
- iOS 用webView加载后台返回的HTML数据
返回数据: <p><b>\U516c\U53f8\U7b80\U4ecb</b></p><p> \U5584\U76c8\U7ba1\ ...
- 【代码笔记】iOS-关于UIFont的一些define
一,效果图. 二,工程图. 三,代码. RootViewController.h #import <UIKit/UIKit.h> @interface RootViewController ...
- 网络邂逅&网络异步请求
什么是卡,网络慢,且你只能等着它加载完不能做别的事 这里便引申出网络异步请求的概念 #import "ViewController.h" @interface ViewContro ...
- art.dialog 返回提示
<form target="_top" /> 1 如果加 target="_top" 提示跳出子页面 2 如果不加则在子页面提示
- java 语言规范 java language specifications
在线地址: https://docs.oracle.com/javase/specs/ java语言规范下载: 链接:http://pan.baidu.com/s/1miEpJwk 密码:f89v j ...
- yii2超好用的日期组件和时间组件
作者:白狼 出处:http://www.manks.top/yii2_datetimepicker.html 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接 ...
- WEB压力测试
原文地址:WEB压力测试 作者:鸟哥のlinux webbench最多可以模拟3万个并发连接去测试网站的负载能力,个人感觉要比Apache自带的ab压力测试工具好,安装使用也特别方便. 1.适用系统: ...
- 编写一个Car类,具有String类型的属性品牌,具有功能drive; 定义其子类Aodi和Benchi,具有属性:价格、型号;具有功能:变速; 定义主类E,在其main方法中分别创建Aodi和Benchi的对象并测试对象的特 性。
package com.hanqi.test; public class Car { //构造一个汽车的属性 private String name; //创建getter和setter方法 publ ...
- EF深入系列--Code First
首先是创建DbContext,有两种途径 ①手动编写DbContext代码,同时还要记得去配置文件中添加connectionStrings public class BooksContext : Db ...
- IDENT_CURRENT ,@@identity,SCOPE_IDENTITY() 之间对比
获取表的标识值,有3种比较常见的用法 IDENT_CURRENT ,@@identity,SCOPE_IDENTITY(),有啥不一样呢? 3个关键字在联机手册中的解释 IDENT_CURRENT ...