额、、失误、、

LCS是Longest Common Subsequence的缩写,即最长公共子序列。一个序列,如果是两个或多个已知序列的子序列,且是所有子序列中最长的,则为最长公共子序列。

DP、O(n^2)解法:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define max(a,b) ((a)>(b)?(a):(b))
#define N 1010 int p,q;
int a[N];
int b[N];
int dp[N][N]; void solve()
{
int i,j;
memset(dp,,sizeof(dp));
for(i=;i<=p;i++)
{
for(j=;j<=q;j++)
{
if(a[i]==b[j])
{
dp[i][j]=dp[i-][j-]+;
}
else
{
dp[i][j]=max(dp[i-][j],dp[i][j-]);
}
}
}
cout<<dp[p][q]<<endl;
}
int main()
{
int i;
while(scanf("%d%d",&p,&q)!=EOF)
{
for(i=;i<=p;i++)
{
scanf("%d",&a[i]);
}
for(i=;i<=q;i++)
{
scanf("%d",&b[i]);
}
solve();
}
return ;
}

O(nlogn)解法:

参考http://www.cs.ucf.edu/courses/cap5937/fall2004/Longest%20common%20subsequence.pdf

最长公共子序列 的 nlogn 的算法本质是 将该问题转化成 最长增序列(LIS),因为 LIS 可以用nlogn实现,所以求LCS的时间复杂度降低为 nlogn。

转化:将LCS问题转化成LIS问题。

               假设有两个序列 s1[ 1~6 ] = { a, b, c , a, d, c }, s2[ 1~7 ] = { c, a, b, e, d, a, b }。

记录s1中每个元素在s2中出现的位置, 再将位置按降序排列, 则上面的例子可表示为:

loc( a)= { 6, 2 }, loc( b ) = { 7, 3 }, loc( c ) = { 1 }, loc( d ) = { 5 }。

将s1中每个元素的位置按s1中元素的顺序排列成一个序列s3 = { 6, 2, 7, 3, 1, 6, 2, 5, 1 }。

在对s3求LIS得到的值即为求LCS的答案。(这点我也只是大致理解,读者可以自己理解甚至证明。)

上面一段话转载自:http://blog.csdn.net/non_cease/article/details/6918848

1、当无重复元素时:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define N 1010 int len;
int p,q;
int a[N];
int b[N];
int dp[N]; void convert()
{
int i,hash[N]={};
for(i=;i<=p;i++)
{
hash[a[i]]=i;
}
for(i=;i<=q;i++)
{
b[i]=hash[b[i]];
}
}
int up_bound(int k)
{
int l=,r=len+;
while(l<r)
{
int m=(l+r)>>;
if(dp[m]<=k) l=m+;
else r=m;
}
return l;
}
void solve()
{
len=;
dp[]=-0x7ffffff;
for(int i=;i<=q;i++)
{
if(!b[i]) continue;
if(b[i]>dp[len]) dp[++len]=b[i];
else
{
int pos=up_bound(b[i]);
dp[pos]=b[i];
}
}
printf("%d\n",len);
}
int main()
{
while(scanf("%d%d",&p,&q)!=EOF)
{
for(int i=;i<=p;i++)
{
scanf("%d",&a[i]);
}
for(int i=;i<=q;i++)
{
scanf("%d",&b[i]);
}
convert();
solve();
}
return ;
}

2、当有重复元素时:

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
#define N 10010 int n;
int p,q;
int len;
int a[N];
int b[N];
int s[N];
int dp[N]; void convert()
{
vector<int> v[N];
for(int i=;i<=p;i++)
{
v[a[i]].push_back(i);
}
n=;
for(int i=;i<=q;i++)
{
for(int j=v[b[i]].size()-;j>=;j--)
{
s[++n]=v[b[i]][j];
}
}
}
int up_bound(int k)
{
int l=,r=len+;
while(l<r)
{
int m=(l+r)>>;
if(dp[m]<=k) l=m+;
else r=m;
}
return l;
} void solve()
{
len=;
dp[]=-0x7fffffff;
for(int i=;i<=n;i++)
{
if(s[i]>dp[len]) dp[++len]=s[i];
else
{
int pos=up_bound(s[i]-);
dp[pos]=s[i];
}
}
printf("%d\n",len);
}
int main()
{
while(scanf("%d%d",&p,&q)!=EOF)
{
for(int i=;i<=p;i++)
{
scanf("%d",&a[i]);
}
for(int i=;i<=q;i++)
{
scanf("%d",&b[i]);
}
convert();
solve();
}
return ;
}

[DP] LCS小结的更多相关文章

  1. UVA.10192 Vacation (DP LCS)

    UVA.10192 Vacation (DP LCS) 题意分析 某人要指定旅游路线,父母分别给出了一系列城市的旅游顺序,求满足父母建议的最大的城市数量是多少. 对于父母的建议分别作为2个子串,对其做 ...

  2. UVA.10066 The Twin Towers (DP LCS)

    UVA.10066 The Twin Towers (DP LCS) 题意分析 有2座塔,分别由不同长度的石块组成.现在要求移走一些石块,使得这2座塔的高度相同,求高度最大是多少. 问题的实质可以转化 ...

  3. UVA-1625-Color Length(DP LCS变形)

    Color Length(UVA-1625)(DP LCS变形) 题目大意 输入两个长度分别为n,m(<5000)的颜色序列.要求按顺序合成同一个序列,即每次可以把一个序列开头的颜色放到新序列的 ...

  4. 插头$DP$学习小结

    插头\(DP\)学习小结 这种辣鸡毒瘤东西也能叫算法... 很优秀的一个算法. 最基本的适用范围主要是数据范围极小的网格图路径计数问题. 如果是像\(Noi2018\)那种的话建议考生在其他两道题难度 ...

  5. UVA 11404 Palindromic Subsequence[DP LCS 打印]

    UVA - 11404 Palindromic Subsequence 题意:一个字符串,删去0个或多个字符,输出字典序最小且最长的回文字符串 不要求路径区间DP都可以做 然而要字典序最小 倒过来求L ...

  6. LightOJ1033 Generating Palindromes(区间DP/LCS)

    题目要计算一个字符串最少添加几个字符使其成为回文串. 一年多前,我LCS这道经典DP例题看得还一知半解时遇到一样的问题,http://acm.fafu.edu.cn/problem.php?id=10 ...

  7. poj 1159 (DP LCS)

    滚动数组 + LCS // File Name: 1159.cpp // Author: Missa_Chen // Created Time: 2013年07月08日 星期一 10时07分13秒 # ...

  8. poj1080--Human Gene Functions(dp:LCS变形)

    Human Gene Functions Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 17206   Accepted:  ...

  9. UVA 531 - Compromise(dp + LCS打印路径)

      Compromise  In a few months the European Currency Union will become a reality. However, to join th ...

随机推荐

  1. Android开发环境搭建(2015年8月更新)

    1.  下载和安装Android SDK Android的官方站点是http://www.android.com: 登录https://developer.android.com/intl/zh-cn ...

  2. Entity Framework 使用sql语句分页(查询单表)

    1.查询单表 var pageSize = 2;//条数 var pageIndex = 2;//索引 var sql = @" SELECT D.* FROM ( SELECT ROW_N ...

  3. /etc/shadow

    这样,用户帐户本身在 /etc/passwd 中定义.Linux 系统包含一个 /etc/passwd 的同伴文件,叫做 /etc/shadow.该文件不像 /etc/passwd,只有对于 root ...

  4. JavaSE生成随机数

    今天呢,老师讲了一下怎么用jvm实现随机数(本人对此很感兴趣),一个简单的随机100以内整数的代码如下: /** 生成随机数 */ import java.util.Random; public cl ...

  5. jQuery对象和Dom对象的区分以及之间转换

    刚开始学习jQuery,可能一时会分不清楚哪些是jQuery对象,哪些是DOM对象.至于DOM对象不多解释,我们接触的太多了,下面重点介绍一下jQuery,以及两者相互间的转换. 一,什么是jQuer ...

  6. 注释玩转webapi

    using System; using System.Collections.Generic; using System.Net.Http.Formatting; using System.Web.H ...

  7. javascript格式化指定的日期对象

    /* * 格式化Date对象为:“2015-04-17 10:20:00” * var dateObj = new Date(); */ function formartDate(dateObj){ ...

  8. Codevs 1183 泥泞的道路

    1183 泥泞的道路 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 传送门 题目描述 Description CS有n个小区,并且任意小区之间都有两条单向道路 ...

  9. Qt 之 QtScript

    前言 前面学习中,很多地方都用到了C++和JavaScript相互通信.今天就学习QtScript模块吧. Qt 包含完全集成的 ECMA 标准脚本引擎.Qt Script 集成了 QObject,为 ...

  10. Android从服务端获取json解析显示在客户端上面

    Android从服务端获取json解析显示在客户端上面 百度经验:jingyan.baidu.com 首先说一下Json数据的最基本的特点,Json数据是一系列的键值对的集合,和XML数据来比,Jso ...