题目的本意是求LCS,但由于每个序列的元素各不相同,所以将A序列重新编号{1,2,,,p+1},将B序列重新编号,分别为B中的元素在A中对应出现的位置(没有的话就是0)。

在样例中就是A = {1 7 5 4 8 3 9},B = {1 4 3 5 6 2 8 9}

重新编号以后:

A = {1 2 3 4 5 6 7}, B = {1 4 6 3 0 0 5 7}(里面的0在求LIS时可以忽略)

这样求A、B的LCS就转变为求B的LIS

求LIS用二分优化,时间复杂度为O(nlogn)

第一次做的用二分求LIS的题是HDU 1025

http://www.cnblogs.com/AOQNRMGYXLMV/p/3862139.html

在这里再复习一遍

 //#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = * ;
int num[maxn], s[maxn], dp[maxn]; int main(void)
{
#ifdef LOCAL
freopen("10635in.txt", "r", stdin);
#endif int T, kase;
scanf("%d", &T);
for(kase = ; kase <= T; ++kase)
{
int N, p, q, x;
scanf("%d%d%d", &N, &p, &q);
memset(num, , sizeof(num));
for(int i = ; i <= p+; ++i)
{
scanf("%d", &x);
num[x] = i;
}
int n = ;
for(int i = ; i <= q+; ++i)
{
scanf("%d", &x);
if(num[x])
s[n++] = num[x];
}
//求s[1]...s[n]的LIS
dp[] = s[];
int len = ;
for(int i = ; i <= n; ++i)
{
int left = , right = len;
while(left <= right)
{
int mid = (left + right) / ;
if(dp[mid] < s[i])
left = mid + ;
else
right = mid - ;
}
dp[left] = s[i];
if(left > len)
++len;
} printf("Case %d: %d\n", kase, len);
}
return ;
}

代码君

大白书里面用到了lower_bound函数

函数介绍

lower_bound()返回一个 iterator 它指向在[first,last)标记的有序序列中可以插入value,而不会破坏容器顺序的第一个位置,而这个位置标记了一个大于value 的值。

效果是一样的

 //#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int INF = ;
const int maxn = * ;
int num[maxn], s[maxn], g[maxn], d[maxn]; int main(void)
{
#ifdef LOCAL
freopen("10635in.txt", "r", stdin);
#endif int T, kase;
scanf("%d", &T);
for(kase = ; kase <= T; ++kase)
{
int N, p, q, x;
scanf("%d%d%d", &N, &p, &q);
memset(num, , sizeof(num));
for(int i = ; i <= p+; ++i)
{
scanf("%d", &x);
num[x] = i;
}
int n = ;
for(int i = ; i <= q+; ++i)
{
scanf("%d", &x);
if(num[x])
s[n++] = num[x];
}
//求s[1]...s[n]的LIS
for(int i = ; i <= n; ++i)
g[i] = INF;
int ans = ;
for(int i = ; i < n; ++i)
{
int k = lower_bound(g+, g+n+, s[i]) - g;
d[i] = k;
g[k] = s[i];
ans = max(ans, d[i]);
}
printf("Case %d: %d\n", kase, ans);
}
return ;
}

代码君

最新文章

  1. float浮动问题:会造成父级元素高度坍塌;
  2. .Net MVC 导入导出Excel总结(三种导出Excel方法,一种导入Excel方法) 通过MVC控制器导出导入Excel文件(可用于java SSH架构)
  3. 怎样删除github中的项目
  4. EL表达式中获取list长度
  5. 第二个Sprint冲刺第七天
  6. 10、android学习资源整理
  7. IIS支持net.tcp
  8. ubuntu 中c 语言编程(学习)
  9. tabBar 选中默认蓝色 ,取消选中(自定义)
  10. Ubuntu 14.02 cmake升级 失败解决
  11. Windows挂钩注入DLL
  12. EasyUI 分页 偶遇 问题
  13. 【搬运】 Page Object 官方文档 (新增了Widget特性)
  14. day84
  15. poj1426_kuagnbin带你飞专题一
  16. POJ.2065.SETI(高斯消元 模线性方程组)
  17. 转:ORACLE 中ROWNUM用法总结!
  18. Python3 - MySQL适配器 PyMySQL
  19. hdu5335(bfs,贪心)
  20. Angular2入门体验

热门文章

  1. HDOJ 1518 Square
  2. Unity3D 将 Unity 嵌入WPF中的一些研究笔记
  3. Win8必知快捷键汇总
  4. URAL1018 Binary Apple Tree(树dp)
  5. POJ 3978 Primes(素数筛选法)
  6. POJ 2081
  7. mysql 中的bool值
  8. IOS笔记 #pragma mark的用法和作用(方便查找和导航代码)
  9. svn教程
  10. sql 泡沫 或者 递归查询