讲一下题目大意,就是有两个长度为p + 1和q + 1的序列,求它们的LCS。

  如果用O(pq)的算法对于这道题来说还是太慢了。所以要另外想一些方法。注意到序列中的所有元素都不相同,所以两个序列中数对应的位置都是唯一的,就用第一个序列的元素对第二个序列的元素进行重新编号,记录它们在第一个序列中出现的位置(如果不存在就随便记一个不能达到的值),不存在的话就说明它们对LCS没有贡献。那么看张图:

  如果不能明白,那。。看张有关不合法情况的图:

  有没有发现LCS的长度就是第二个序列的LIS的长度?

 /**
* uva
* Problem#10635
* Accepted
* Time:0ms
*/
#include<iostream>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<sstream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<stack>
using namespace std;
typedef bool boolean;
#define INF 0xfffffff
#define smin(a, b) a = min(a, b)
#define smax(a, b) a = max(a, b)
template<typename T>
inline void readInteger(T& u){
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != '-');
if(x == '-'){
x = getchar();
aFlag = -;
}
for(u = x - ''; isdigit((x = getchar())); u = (u << ) + (u << ) + x - '');
ungetc(x, stdin);
u *= aFlag;
} template<typename T>
class IndexedStack{
public:
T *p;
int s;
IndexedStack():s(), p(NULL){ }
IndexedStack(int size):s(){
p = new T[(const int)size];
}
boolean empty() { return s == ; }
T top() { return p[s - ]; }
int size() { return s; }
void pop() { s--; }
void push(T& x) { p[s++] = x; }
void clear() { s = ; }
T& operator [](int pos) { return p[pos]; }
}; int n, p, q;
int *pce;
int *pss;
int *ets; inline void init(){
readInteger(n);
readInteger(p);
readInteger(q);
pce = new int[(const int)(p + )];
pss = new int[(const int)(q + )];
ets = new int[(const int)(n * n + )];
memset(ets, , sizeof(int) * (n * n + ));
p += , q += ;
for(int i = ; i <= p; i++){
readInteger(pce[i]);
ets[pce[i]] = i;
}
for(int i = ; i <= q; i++){
readInteger(pss[i]);
pss[i] = ets[pss[i]];
}
delete[] ets;
} int upper_bound(int *a, int from, int end, int val){
int l = from, r = end - ;
while(l <= r){
int mid = (l + r) >> ;
if(val < a[mid]) r = mid - ;
else l = mid + ;
}
return r + ;
} IndexedStack<int> s;
inline int lis(){
s = IndexedStack<int>(q + );
for(int i = ; i <= q; i++){
if(pss[i] == ) continue;
int l = upper_bound(s.p, , s.size(), pss[i]);
if(l == s.size()) s.push(pss[i]);
else s[l] = pss[i];
}
return s.size();
} int T, kase;
inline void solve(){
int len = lis();
printf("Case %d: %d\n", kase, len);
delete[] pss;
delete[] pce;
} int main(){
readInteger(T);
while(T--){
kase++;
init();
solve();
}
return ;
}

最新文章

  1. Atitit 图像处理 调用opencv 通过java &#160;api &#160;&#160;attilax总结
  2. Java进击C#——语法之知识点的改进
  3. 关于Chrome Dev Tool
  4. SOAP+WSDL
  5. UVa 101 (模拟) The Blocks Problem
  6. win10 uwp iot
  7. Python爬虫(十一)_案例:使用正则表达式的爬虫
  8. JAVA_SE基础——8.基本数据类型
  9. Docker学习实践 - Docker安装MySql数据库
  10. Microsoft Office Excel cannot access the file, There are several possible reasons
  11. Flink部署-standalone模式
  12. 运行vue遇到的坑(续更
  13. js如何获取字符串第几次出现的位置
  14. 使用nginx运行thinkphp的nginx配置
  15. Windows7 密码修改
  16. Using The jQuery Migrate Plugin
  17. 【Java入门提高篇】Day20 Java容器类详解(三)List接口
  18. springboot+dubbo+zookeeper微服务实践demo
  19. jQuery的attr方法处理checkbox的问题
  20. 使用minGW/cygwin在Windows是用于gcc开发

热门文章

  1. Bootstap datetimepicker报错TypeError: intermediate value(转)
  2. Java注释Override、Deprecated、SuppressWarnings详解(过时方法,即将删除的方法或成员变量)
  3. for xml path(&#39;&#39;),root(&#39;&#39;)
  4. Unity3D外包团队——技术分享U3D全景漫游(三)
  5. ADO.NET数据库操作助手类
  6. [ActionScript 3.0] AS3.0 简单封装Socket的通信
  7. silverlight 鼠标事件处理
  8. php rmdir使用递归函数删除非空目录
  9. LINUX下WIFI默认连接
  10. React 附件动画API ReactCSSTransitionGroup