【Luogu P1439】最长公共子序列(LCS)
Luogu P1439
令f[i][j]表示a的前i个元素与b的前j个元素的最长公共子序列
可以得到状态转移方程:
if (a[i]==b[j]) dp[i][j]=dp[i-1][j-1]+1;
dp[i][j]=max(dp[i][j],dp[i-1][j],dp[i][j-1]);
时空复杂度都为O(n2)
对于本题这种做法显然是无法接受的。
我们可以对这个题目进行转化。仔细看题,可以发现a,b两个序列都是1-n的排列。
那么,我们可以利用映射,将a中的数一一映射成为1,2,3,4,5……,n
再把b中的数一一对应更改。由于a中的数是升序的,所以b中的最长上升子序列的长度就是a与b的最长公共子序列。LCS问题就转化成了LIS问题。
例如样例
a的 3 2 1 4 5映射为1 2 3 4 5
则b从1 2 3 4 5变为3 2 1 4 5
结合上面的分析就会变得很容易理解了。
#include<algorithm>
#include<cstdio>
using namespace std;
int n,a[100005],b[100005],k[100005],dp[100005],ans;
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
k[a[i]]=i;
}
for (int i=1;i<=n;i++)
{
scanf("%d",&b[i]);
b[i]=k[b[i]];
}
dp[1]=1;
for (int i=2;i<=n;i++)
{
for (int j=1;j<i;j++)
{
if (b[i]>b[j]) dp[i]=max(dp[i],dp[j]+1);
else dp[i]=max(1,dp[i]);
}
}
for (int i=1;i<=n;i++)
ans=max(ans,dp[i]);
printf("%d",ans);
return 0;
}
这个动态规划可以很轻松地写出来,但是我们发现时间还是不够优秀。
那么我们就要对这个算法进行优化。对于LIS问题,有一种广为人知的O(nlogn)的解法。
dp[i]中存储长度为i的LIS的最后一个数。
如果符合单调上升就直接增长长度并记录,否则就利用STL二分查找出dp数组中第一个大于b[i]的位置,替换它。
举个例子,例如 3 6 2 4 7 8
一开始的序列{3},接着变成{3,6}
遇到2之后我们将3替换{2,6},为什么可以进行替换呢?
因为后面还有一个4可以替换掉6,构成一条更优的序列。(保证结尾尽可能小,就能保证序列尽可能优)
如果后面没有4呢?那么也没有关系,因为这个2即使修改了也对答案没有任何影响。
(想一想为什么)
dp[1]=b[1];
len=1;
for (int i=2;i<=n;i++)
{
if (b[i]>dp[len]) dp[++len]=b[i];//记录并增长长度。
else
{
int x=upper_bound(dp+1,dp+1+len,b[i])-dp;
dp[x]=b[i];
//利用STL二分查找出dp数组中第一个大于b[i]的位置,替换它。
}
}
完整代码如下:
#include<algorithm>
#include<cstdio>
using namespace std;
int n,a[100005],b[100005],k[100005],dp[100005],ans,len;
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
k[a[i]]=i;//映射
}
for (int i=1;i<=n;i++)
{
scanf("%d",&b[i]);
b[i]=k[b[i]];//对应修改
}
dp[1]=b[1];
len=1;
for (int i=2;i<=n;i++)
{
if (b[i]>dp[len]) dp[++len]=b[i];
else
{
int x=upper_bound(dp+1,dp+1+len,b[i])-dp;
dp[x]=b[i];
}
}
printf("%d",len);
return 0;
}
【Luogu P1439】最长公共子序列(LCS)的更多相关文章
- Luogu 3402 最长公共子序列(二分,最长递增子序列)
Luogu 3402 最长公共子序列(二分,最长递增子序列) Description 经过长时间的摸索和练习,DJL终于学会了怎么求LCS.Johann感觉DJL孺子可教,就给他布置了一个课后作业: ...
- 1006 最长公共子序列Lcs
1006 最长公共子序列Lcs 基准时间限制:1 秒 空间限制:131072 KB 给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdks ...
- 动态规划之最长公共子序列LCS(Longest Common Subsequence)
一.问题描述 由于最长公共子序列LCS是一个比较经典的问题,主要是采用动态规划(DP)算法去实现,理论方面的讲述也非常详尽,本文重点是程序的实现部分,所以理论方面的解释主要看这篇博客:http://b ...
- 编程算法 - 最长公共子序列(LCS) 代码(C)
最长公共子序列(LCS) 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 给定两个字符串s,t, 求出这两个字符串最长的公共子序列的长度. 字符 ...
- C++版 - Lintcode 77-Longest Common Subsequence最长公共子序列(LCS) - 题解
版权声明:本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C++版 - L ...
- POJ 1458 Common Subsequence(最长公共子序列LCS)
POJ1458 Common Subsequence(最长公共子序列LCS) http://poj.org/problem?id=1458 题意: 给你两个字符串, 要你求出两个字符串的最长公共子序列 ...
- 51Nod 1006:最长公共子序列Lcs(打印LCS)
1006 最长公共子序列Lcs 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). ...
- 51nod 1006 最长公共子序列Lcs 【LCS/打印path】
1006 最长公共子序列Lcs 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). ...
- 每日一题-——最长公共子序列(LCS)与最长公共子串
最长公共子序列(LCS) 思路: 代码: def LCS(string1,string2): len1 = len(string1) len2 = len(string2) res = [[0 for ...
- 51nod 1006:最长公共子序列Lcs
1006 最长公共子序列Lcs 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). ...
随机推荐
- todoList.html
待做的事情 {{item}} 完成 <!DOCTYPE html> <html> <head> <meta charset="UTF-8" ...
- SpringCloud Config(配置中心)实现配置自动刷新(十六)
一.实现原理 1.ConfigServer(配置中心服务端)从远端git拉取配置文件并在本地git一份,ConfigClient(微服务)从ConfigServer端获取自己对应 配置文件: 2.当远 ...
- ulua、tolua原理解析
在聊ulua.tolua之前,我们先来看看Unity热更新相关知识. 什么是热更新 举例来说: 游戏上线后,玩家下载第一个版本(70M左右或者更大),在运营的过程中,如果需要更换UI显示,或者修改游戏 ...
- Linux Cannot allocate memory问题
查找了一下相关文档,发现这个错误的含义其实就是像它自己说的,没法分配内存了. The problem is inherent with the way Java allocates memory wh ...
- 明解C语言 入门篇 第三章答案
练习3-1 #include <stdio.h> int main() { int x; int y; puts("请输入两个整数."); printf("整 ...
- Linux下搭建.NetCore3.0环境及创建项目
================================================== ================================================= ...
- 帝国cms7.5免登陆发布模块
帝国cms7.5免登陆发布文章. 帝国cms增加了金刚模式,登录发布文章有难度.免登录发布模块配合火车采集器,完美解决你遇到的问题. 1.必备工具: 1.火车采集器 2.免登陆发布接口 3.帝国cms ...
- 在linux用ueditor遇到的问题
在使用ueditor时,遇到很多问题.最大问题是就是服务器返回出错 最让人头疼的是preview没有任何信息.之前也找过很多的资料,很多资料都没有提到修改controller.php文件中error_ ...
- 2019年10月13日 spss习题 wangqingchao
1.spss发行版本的说法,正确的是:B a.两年发行一个新版本 b.一年发行一个新版本 c.没有任何规律 d.三年发行一个新版本 2.哪些是spss统计分析软件的基本窗口:A a.结果查看 ...
- Prometheus客户端开发:腾讯云CLB
一:简介 随着prometheus的使用人群逐渐扩大,官方定义的client exporter虽然能满足我们的大部分需求,但是很多监控还是需要我们自定义开发,以下内容就是基于腾讯云SDK,对腾讯云CL ...