【模板】最长公共子序列
来源:互联网 发布:日有所思夜有所梦 知乎 编辑:程序博客网 时间:2024/06/05 19:43
题目
对于O(nlogn)搞一个最长上升子序列
考虑一个数列5 2 3 1 4
首先 把5加入答案序列中 然后加2 发现2<5所以显然2替换5不会使结果更差 那么答案序列就是{2} 然后加3 发现3>2 所以直接把3加到答案序列中 {2,3}
然后加1 我们发现1<3 于是我们找到一个最小的但是比1大的数字2 然后把1替换2 为什么这么做不会影响结果呢?我们当前已经求出了一个当前最优的序列 如果我们用1替换2 然后后面来一个数字替换了3 那么我们就可以得到一个更优的序列 而如果没有数字替换3 那么这个1替换2也就是没有贡献的 不会影响我们结果的最优性
可以用lower_bound二分查找
然后对于最长公共子序列 就是两段所含数字完全一样 并且数字的顺序也是完全一样的序列
我们建立一个关系数组f[ai]=i 那么我们找到的序列只要是上升的 顺序就是一样的 然后考虑数字完全一样 由于我们已经有了一个f[ai]=i 所以我们把对应的bi改成f[bi] 就可以确保数字相等了 然后在f[bi]的数组中求个最长上升子序列了 二分即可
一开始我也不懂 后来手推了一下
代码如下
#include<iostream>#include<cstdio>#include<cctype>#include<algorithm>#include<cstring>#include<string> using namespace std; #define in = read() typedef long long ll; typedef unsigned int ui; const ll size = 100000 + 10000; int n; int x , y; int num[size] , cur[size];inline ll read(){ ll num = 0 , f = 1; char ch = getchar(); while(!isdigit(ch)){ if(ch == '-') f = -1; ch = getchar(); } while(isdigit(ch)){ num = num*10 + ch - '0'; ch = getchar(); } return num*f;}int main(){ memset(cur , 127/3 , sizeof(cur)); n in; for(register int i=1;i<=n;i++){ x in; num[x] = i; } for(register int i=1;i<=n;i++){ y in; x = num[y]; *lower_bound(cur + 1 , cur + n + 1 , x) = x; } printf("%d" , lower_bound(cur + 1 , cur + n + 1 , cur[0]) - cur - 1); return 0;}//COYG
阅读全文
0 0
- 最长公共子序列【模板】
- 【模板】最长公共子序列
- 最长公共子序列模板
- 最长公共子序列【模板】
- 【模板】最长公共子序列
- 模板 - 最长公共子序列
- 【模板】最长公共子序列
- 【模板】最长公共子序列
- 最长公共子序列和最长递增子序列模板
- 【模板】最长公共上升子序列
- 【模板】最长递增公共子序列
- 最长公共递增子序列【模板】
- 【模板】最长递增公共子序列
- 最长公共子序列(1)--hdu1159(模板)
- [模板]求最长公共子序列
- 最长公共子序列LCS模板
- 个人模板 最长公共连续子序列
- 个人模板 最长公共子序列
- 计算C(2n, n)
- Luogu 3371(dijkstra堆优化)
- HELLO,21
- 浅谈几种服务器端模型——同步阻塞迭代
- Linux环境下mosquitto的安装及部分问题解决方法
- 【模板】最长公共子序列
- 【Mybatis学习】Mybatis级联之一对多
- 【51nod】1012 最小公倍数LCM
- 每日一练10.31
- Java面向对象(1)
- nodemon文件修改后自动运行node
- [App] rhel7 下 安装 JBoss7
- Android架构图 (5层)
- 8queen(稍后补)