CJOJ 2044 【一本通】最长公共子序列(动态规划)

Description

一个给定序列的子序列是在该序列中删去若干元素后得到的序列。确切地说,若给定序列X,则另一序列Z是X的子序列是指存在一个严格递增的下标序列 ,使得对于所有j=1,2,…,k有 Xij=Zj 。

例如,序列Z是序列X的子序列,相应的递增下标序列为<2,3,5,7>。

给定两个序列X和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。

最长公共子序列(LCS)问题:给定两个序列X=和Y=,要求找出X和Y的一个最长公共子序列。

Input

输入两行,每行由大写字母构成的长度不超过200的字符串,表示序列X和Y

Output

第一行非负整数N,表示最长公共子串的长度,若不存在公共子序列输出0.

第二行输出最长的公共子序列(若存在多个,输出最先出现的最长公共子序列)

Sample Input

ABCDDAB

BDCABA

Sample Output

4

Http

CJOJ:http://oj.changjun.com.cn/problem/detail/pid/2044

Source

动态规划

解决思路

这道题是一道动态规划的经典题目。

我们定义F[i][j]表示字符串A的前i位和字符串B的前j位能取到的最长公共子序列,那么自然有F[i][0]均为0,F[0][i]也均为0。

首先我们可以确定的是对于任意的F[i][j],均可以从F[i-1][j](即字符串A减去一个字符)和F[i][j-1](即字符串B减去一个字符)得到,所以必有F[i][j]=min(F[i-1][j]+F[i][j-1])。那么如果A[i]==B[j],则说明F[i][j]还可以从F[i-1][j-1]推得。

所以,综上所述,动态转移方程就是

\[F[i][j]=min(F[i-1][j-1],F[i-1][j],F[i][j-1]) (A[i]==B[j])
=min(F[i-1][j],F[i][j-1]) (Other)\]

另外,这道题的加强版在这里。因为数据范围的关系,不能在使用本题这种动态规划 的方法。

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
using namespace std; const int maxN=300;
const int inf=2147483647; string A;
string B;
int F[maxN][maxN]; int main()
{
memset(F,0,sizeof(F));
cin>>A>>B;
for (int i=0;i<A.size();i++)
F[i][0]=0;
for (int i=0;i<B.size();i++)
F[0][i]=0;
for (int i=1;i<=A.size();i++)
for (int j=1;j<=B.size();j++)
if (A[i-1]==B[j-1])
{
F[i][j]=max(F[i-1][j-1]+1,max(F[i-1][j],F[i][j-1]));
}
else
F[i][j]=max(F[i-1][j],F[i][j-1]);
cout<<F[A.size()][B.size()]<<endl;
return 0;
}

CJOJ 2044 【一本通】最长公共子序列(动态规划)的更多相关文章

  1. 【ACM】最长公共子序列 - 动态规划

    最长公共子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共子序列.tip:最长公共子序列也称作最 ...

  2. C++求解汉字字符串的最长公共子序列 动态规划

        近期,我在网上看了一些动态规划求字符串最长公共子序列的代码.可是无一例外都是处理英文字符串,当处理汉字字符串时.常常会出现乱码或者不对的情况. 我对代码进行了改动.使用wchar_t类型存储字 ...

  3. nyoj 36-最长公共子序列 (动态规划,DP, LCS)

    36-最长公共子序列 内存限制:64MB 时间限制:3000ms Special Judge: No accepted:18 submit:38 题目描述: 咱们就不拐弯抹角了,如题,需要你做的就是写 ...

  4. 动态规划之最长公共子序列(LCS)

    转自:http://segmentfault.com/blog/exploring/ LCS 问题描述 定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 ...

  5. 动态规划求最长公共子序列(Longest Common Subsequence, LCS)

    1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...

  6. 动态规划(一)——最长公共子序列和最长公共子串

    注: 最长公共子序列采用动态规划解决,由于子问题重叠,故采用数组缓存结果,保存最佳取值方向.输出结果时,则自顶向下建立二叉树,自底向上输出,则这过程中没有分叉路,结果唯一. 最长公共子串采用参考串方式 ...

  7. 动态规划 - 最长公共子序列(LCS)

    最长公共子序列也是动态规划中的一个经典问题. 有两个字符串 S1 和 S2,求一个最长公共子串,即求字符串 S3,它同时为 S1 和 S2 的子串,且要求它的长度最长,并确定这个长度.这个问题被我们称 ...

  8. 算法导论-动态规划(最长公共子序列问题LCS)-C++实现

    首先定义一个给定序列的子序列,就是将给定序列中零个或多个元素去掉之后得到的结果,其形式化定义如下:给定一个序列X = <x1,x2 ,..., xm>,另一个序列Z =<z1,z2  ...

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

    hdu1159 题目要求两个字符串最长公共子序列, 状态转换方程   f[i][j]=f[i-1][j-1]+1; a[i]=b[j]时 f[i][j]=MAX{f[i-1][j],f[i][j-1] ...

随机推荐

  1. javascript闭包小结

    对比看了几本书关于闭包的介绍,感觉<JavaScript面向对象编程指南>一书中介绍的最为清楚,其他部分书籍很多只讲结果,不讲具体原因,不易理解.总结如下 1.闭包的定义 如果一个函数会在 ...

  2. docker安装与学习

    docker学习 以ubuntu为实例 第一步检查系统内核>3.80 第二步 安装Docker 之前先更新apt-get update 在执行安装命令 apt-get install -y do ...

  3. Java静态代理与动态代理模式的实现

    前言:    在现实生活中,考虑以下的场景:小王打算要去租房,他相中了一个房子,准备去找房东洽谈相关事宜.但是房东他很忙,平时上班没时间,总找不到时间去找他,他也没办法.后来,房东想了一个办法,他找到 ...

  4. Java 9 揭秘(1.Java入门介绍)

    文 by / 林本托 在第一部分中,主要讲解如下内容: JDK 9 包含了哪些内容 运行代码的系统要求 如何安装 NetBeans 1 JDK 介绍 JDK 9是Java开发工具包的第九个主要版本,计 ...

  5. 从零开始的JS生活(三)——内置对象

    咱们继续进行我们的正经的JS介绍.今天所要跟大家讲述的是JS中十分常用.十分常用.十分常用的内置对象. 一.世界上最熟悉的陌生就是,当你看着数组.而我看着你... - 数组对象 1.数组的概念 在内存 ...

  6. 一天搞定CSS:表格(table)--19

    1.表格标签 表格标签的嵌套关系 <table> <!--表格头--> <thead> <!--表格行--> <tr> <!--表格列 ...

  7. Java IO流之转换流

    一.转换流 1.在IO包中,实际上就是分为字节流和字符流,但是除了这两个流之外,还存在了一组字节流-字符流的转换流 2.转换流用于在字节流和字符流之间转换 3.转换流本身是字符流 二.两种转换流 Ou ...

  8. javaSE_06Java中的数组(array)-思维导图

    思维导图看不清楚时: 1)可以将图片另存为图片,保存在本地来查看 : 2)右击在新标签中打开放大查看 (IE不支持,搜狗,360可以):

  9. ssh框架整合之登录以及增删改查

    1.首先阐述一下我用得开发工具,myeclipse2017+oracle,所以我的基本配置步骤可能不一样,下面我用几张图来详解我的开发步骤. ---1先配置structs (Target 选择apac ...

  10. 利用React/anu编写一个弹出层

    本文将一步步介绍如何使用React或anu创建 一个弹出层. React时代,代码都是要经过编译的,我们很多时间都耗在babel与webpack上.因此本文也介绍如何玩webpack与babel. 我 ...