[luoguP1439] 排列LCS问题(DP + 树状数组)
无重复元素的LCS问题
n2 做法不说了。
nlogn 做法 ——
因为LCS问题求的是公共子序列,顺序不影响答案,影响答案的只是两个串的元素是否相同,所以可以交换元素位置。
首先简化一下问题,假设P1恰好为单调递增的1,2,3,...n,那么很显然答案就是P2的最长上升子序列的长度
问题是P1并非单调递增的,但我们可以假定它就是1,2,3,...,n。
也就是重新定义一下第一个串中 所有数 的顺序,定义a[x] = i,也就是 数x 是第 i 个,然后再重新弄一下第二串的顺序,最后求一遍lis。
——代码
#include <cstdio>
#include <algorithm>
#include <cstring> using namespace std; const int MAXN = ;
int n, ans;
int a[MAXN], b[MAXN], c[MAXN]; inline int query(int x)
{
int ans = ;
for(; x; x -= x & -x) ans = max(ans, c[x]);
return ans;
} inline void update(int x, int d)
{
for(; x <= n; x += x & -x) c[x] = max(c[x], d);
} int main()
{
int i, j, x, y;
scanf("%d", &n);
for (i = ; i <= n; i++) scanf("%d", &x), a[x] = i;
for (i = ; i <= n; i++) scanf("%d", &x), b[i] = a[x];
for(i = ; i <= n; i++)
{
y = query(b[i] - ) + ;
update(b[i], y);
ans = max(ans, y);
}
printf("%d", ans);
return ;
}
还有另一种思路。也是 nlogn,而且比较好理解。(说实话,我真不理解上面的映射是怎么弄的)
原本 n2 做法是设 f[i][j] 表示 第一串的前 i 个数 和 第二串的前 j 个数 的最优答案(i 和 j 都不必须选),然后一阵乱搞。
nlogn——
可以改变状态的定义,f[i][j] 表示 第一串的前 i 个数 和 第二串的前 j 个数 的最有答案(i 不必须选,j 必须选)
这样 f[i][] 只能由 f[i - 1][] 转移过来,这样就变成了分层的DP,并且只转移到 f[i][k] (其中 b[k] == a[i]),也就是只影响一个答案。
所以先记录和 a[i] 相同的 b[j] 的位置,然后 f 数组可以变成一维,动态维护 f 数组即可。
f[i] = max(f[j]) + 1 ( 1 <= j < i && a[i] == b[j])
——代码
#include <cstdio>
#include <iostream> using namespace std; const int MAXN = ;
int n, ans;
int a[MAXN], b[MAXN], c[MAXN], p[MAXN], f[MAXN]; inline int query(int x)
{
int ret = ;
for(; x; x -= x & -x) ret = max(ret, c[x]);
return ret;
} inline void update(int x, int d)
{
for(; x <= n; x += x & -x) c[x] = max(c[x], d);
} int main()
{
int i;
scanf("%d", &n);
for(i = ; i <= n; i++) scanf("%d", &a[i]);
for(i = ; i <= n; i++) scanf("%d", &b[i]), p[b[i]] = i;
for(i = ; i <= n; i++)
{
f[p[a[i]]] = query(p[a[i]] - ) + ;
update(p[a[i]], f[p[a[i]]]);
ans = max(ans, f[p[a[i]]]);
}
printf("%d", ans);
return ;
}
[luoguP1439] 排列LCS问题(DP + 树状数组)的更多相关文章
- bzoj 1264 [AHOI2006]基因匹配Match(DP+树状数组)
1264: [AHOI2006]基因匹配Match Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 793 Solved: 503[Submit][S ...
- 树形DP+树状数组 HDU 5877 Weak Pair
//树形DP+树状数组 HDU 5877 Weak Pair // 思路:用树状数组每次加k/a[i],每个节点ans+=Sum(a[i]) 表示每次加大于等于a[i]的值 // 这道题要离散化 #i ...
- 【bzoj2274】[Usaco2011 Feb]Generic Cow Protests dp+树状数组
题目描述 Farmer John's N (1 <= N <= 100,000) cows are lined up in a row andnumbered 1..N. The cows ...
- 奶牛抗议 DP 树状数组
奶牛抗议 DP 树状数组 USACO的题太猛了 容易想到\(DP\),设\(f[i]\)表示为在第\(i\)位时方案数,转移方程: \[ f[i]=\sum f[j]\;(j< i,sum[i] ...
- 第十四个目标(dp + 树状数组 + 线段树)
Problem 2236 第十四个目标 Accept: 17 Submit: 35 Time Limit: 1000 mSec Memory Limit : 32768 KB Probl ...
- Codeforces 1096F(dp + 树状数组)
题目链接 题意: 对于长度为$n$的排列,在已知一些位的前提下求逆序对的期望 思路: 将答案分为$3$部分 $1.$$-1$与$-1$之间对答案的贡献.由于逆序对考虑的是数字之间的大小关系,故假设$- ...
- [CF1086E]Beautiful Matrix(容斥+DP+树状数组)
给一个n*n的矩阵,保证:(1)每行都是一个排列 (2)每行每个位置和上一行对应位置不同.求这个矩阵在所有合法矩阵中字典序排第几.考虑类似数位DP的做法,枚举第几行开始不卡限制,那么显然之前的行都和题 ...
- Codeforces 1085G(1086E) Beautiful Matrix $dp$+树状数组
题意 定义一个\(n*n\)的矩阵是\(beautiful\)的,需要满足以下三个条件: 1.每一行是一个排列. 2.上下相邻的两个元素的值不同. 再定义两个矩阵的字典序大的矩阵大(从左往右从上到下一 ...
- BZOJ 4361 isn 容斥+dp+树状数组
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4361 题意概述: 给出一个长度为N的序列A(A1,A2...AN).如果序列A不是非降的 ...
- codeforces 597C C. Subsequences(dp+树状数组)
题目链接: C. Subsequences time limit per test 1 second memory limit per test 256 megabytes input standar ...
随机推荐
- B - Archer
Problem description SmallR is an archer. SmallR is taking a match of archer with Zanoes. They try to ...
- 加密解密(3)Bob到CA申请证书过程
网络安全中最知名的人物大概就是Bob和Alice了,因为很多安全原理阐述中都用这两个虚拟人物来进行实例说明. 我们来看看Bob是怎么从CA中心获得一个数字证书的: 1.Bob首先创建他自己的密钥对(k ...
- [转]C#Linq中的Union All/Union/Intersect和Top/Bottom和Paging和SqlMethods,skip,take,takewhile,skipwhile,编译查询等
本文转自:http://www.cnblogs.com/suizhikuo/p/3791799.html 我们继续讲解LINQ to SQL语句,这篇我们来讨论Union All/Union/Inte ...
- Uml 建模 一(类图建模和startuml的使用)
本文将分三个部分介绍Uml建模:Uml建模的作用.类图.startuml的使用 Uml的作用 本文以java为例介绍Uml,在当前的软件开发中大多数使用面向对象开发(OO),面向对象的就是将现实世界中 ...
- 掌握Spark机器学习库-07-随机梯度下降
1)何为随机梯度下降 优化方法 迭代更新,来寻找函数全局最优解的方法 与最小二乘法相比:适用于变量众多,模型更复杂 2)梯度 变化最快,“陡峭” 通过函数表达式来衡量梯度 3)随机梯度下降原理推导过程 ...
- R in action读书笔记(6)-第七章:基本统计分析(中)
7.2 频数表和列联表 > library(vcd) > head(Arthritis) ID Treatment Sex Age Improved 1 57 Treated Male 2 ...
- C++ 类、对象、class
一.对象初始化 1.不能在类声明中对数据成员初始化,因为类只是一个抽象类型,不占存储空间,无处容纳数据. 2.若某类的数据成员都是public,则可以像结构体一样初始化,如 Time t={12,21 ...
- CRegKey
1.简介 CRegKey提供了对系统注册表的操作方法,通过CRegKey类,可以方便的打开注册表的某个分支或子键(CRegKey::Open),可以方便的修改一个键的键值(CRegKey::SetVa ...
- redis的安装总结
1. 下载redis安装包:> 可以用命令: wget http://download.redis.io/releases/redis-5.0.5.tar.gz, 或者直接从官网下载.2. 解压 ...
- ie兼容的解决办法,6,7、8、9、10
在网站开发中不免因为各种兼容问题苦恼,针对兼容问题,其实IE给出了解决方案Google也给出了解决方案百度也应用了这种方案去解决IE的兼容问题 百度源代码如下 <!Doctype html> ...