传送门

$Description$

求两个序列的最长公共上升子序列

$Solution$

$f[i][j]$表示$a$序列匹配到$i$和$b$序列匹配到$j$的最长上升序列的长度,这里并不要求$a[i]==b[j]$。

两层循环,外层$i=1...n1$,内层$j=1...n2$

转移:

$f[i][j]=max(f[i-1][1...j-1](if\  b[j]<a[i]))+1$

这里的$max(f[i-1][i...j-1](if\  b[j]<a[i]))$不用每次单独枚举,只要在循环内即使更新就可以了

或者,也可以用树状数组来维护.

$Code$

#include<bits/stdc++.h>
#define Ri register int
#define il inline
#define go(i,a,b) for(Ri i=a;i<=b;++i)
#define yes(i,a,b) for(Ri i=a;i>=b;--i)
#define e(i,u) for(Ri i=b[u];i;i=a[i].nt)
#define ll long long
#define db double
using namespace std;
il int read()
{
Ri x=,y=;char c=getchar();
while(c<'' || c>''){if(c=='-')y=-;c=getchar();}
while(c>='' && c<=''){x=(x<<)+(x<<)+c-'';c=getchar();}
return x*y;
}
const int N=;
int n,m,a[N],b[N],f[N][N],as,d[N],t[N][N*];
struct nd{int d,p;}c[N];
il bool cmp(nd x,nd y){return x.d<y.d;}
il int lowbit(Ri x){return x&(-x);}
il void change(Ri i,Ri j,Ri dat)
{
while(i<=n)
{
t[j][i]=max(t[j][i],dat);
i+=lowbit(i);
}
}
il int sum(Ri i,Ri j)
{
Ri ret=;
while(i>)
{
ret=max(ret,t[j][i]);
i-=lowbit(i);
}
return ret;
}
int main()
{
freopen("lcis.in","r",stdin);
freopen("lcis.out","w",stdout);
n=read(),m=read();
go(i,,n)a[i]=read(),c[i]=(nd){a[i],i};
go(i,,m)b[i]=read();
sort(c+,c+n+,cmp);
go(i,,n)
if(i>= && c[i].d==c[i-].d)d[c[i].p]=d[c[i-].p];
else d[c[i].p]=i;
go(i,,n)
{
go(j,,m)
{
f[i][j]=max(f[i][j],f[i][j-]);
if(a[i]==b[j])
f[i][j]=max(f[i][j],sum(d[i]-,j-)+);
}
go(j,,m)change(d[i],j,f[i][j]);
}
go(i,,n)as=max(as,f[i][m]);
printf("%d\n",as);
return ;
}

View 树状数组 Code

 #include<iostream>
#include<cstdio>
#include<cstring>
#define Rg register
#define il inline
#define db double
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a));
#define go(i,a,b) for(Rg int i=a;i<=b;i++)
#define yes(i,a,b) for(Rg int i=a;i>=b;i--)
using namespace std;
il int read()
{
int x=,y=;char c=getchar();
while(c<''||c>''){if(c=='-')y=-;c=getchar();}
while(c>=''&&c<=''){x=(x<<)+(x<<)+c-'';c=getchar();}
return x*y;
}
const int N=;
int T,n1,n2,ans,a[N],b[N],al[N],f[N][N],lst[N][N];
il void sol()
{
ans=;mem(f,);int x=n1,y=,t;
go(i,,n1)
{
t=;
go(j,,n2)
{
if(a[i]!=b[j])f[i][j]=f[i-][j];
if(a[i]>b[j]&&f[i][j]>f[i][t])t=j;
if(a[i]==b[j])f[i][j]=f[i][t]+,lst[i][j]=t;
//cout<<"f["<<i<<"]["<<j<<"]:"<<f[i][j]<<endl;
}
}
go(i,,n2)if(f[n1][i]>ans)ans=f[n1][i],y=i;
t=;
while(f[x][y])
{
while(a[x]!=b[y]){x--;if(!x)return;}
al[ans-t]=b[y],y=lst[x][y],t++;
}
}
int main()
{
T=read();
while(T--)
{
n1=read();go(i,,n1)a[i]=read();
n2=read();go(i,,n2)b[i]=read();
sol();
printf("%d\n",ans);
if(ans){go(i,,ans)printf("%d ",al[i]);printf("\n");}
}
return ;
}

随机推荐

  1. MySQL列出当前月的每一天

    因为工作的原因,要用MySQL列出当前月份每一天的日期,自己查了下网上资料都是列出最近一个月的日期的解决方案,自己根据查到的的方案,修改成了下面两个方案,在此记录下: 方案一: SELECT date ...

  2. 一条数据的漫游 -- X-Engine SIGMOD Paper Introduction

    大多数人追寻永恒的家园(归宿),少数人追寻永恒的航向. ----瓦尔特.本雅明 背景 X-Engine是阿里数据库产品事业部自研的OLTP数据库存储引擎,作为自研数据库POLARDB X的存储引擎,已 ...

  3. P1144 最短路计数 题解 最短路应用题

    题目链接:https://www.luogu.org/problem/P1144 其实这道题目是最短路的变形题,因为数据范围 \(N \le 10^6, M \le 2 \times 10^6\) , ...

  4. ITA 15.5 Optimal binary search trees

    p400 页最后一段 When j >= i , we need to select a root kr from among ki ... kj and then make an optima ...

  5. pip、conda 换国内源,大大提高下载速度

    https://www.jianshu.com/p/b2d53904dd37 源就是下载地址了,换到国内的源下载速度真的快了近10倍,这里都用了清华的源 pip 只要新建一个配置文件,写上路径就行了 ...

  6. HDU 1568

    - - 我自己开始以为是数值范围是1到100000000.... 搞了半天才发现是斐波那契数列的项数1到100000000 坑爹.!! 不会,只能看网上大牛的题解. 具体解释请看:http://www ...

  7. vue样式加scoped后不能覆盖组件的原有样式解决方法

    <style scoped> </style> 为了vue页面样式模块化,不对全局造成污染,建议每个页面的style标签加上scoped,表示他的样式只属于当前的页面,父组件的 ...

  8. 关于Character的digit,forDigit,getNumericValue方法的一点理解

    Character类是一个包装类. char这种数据类型是基于原始的Unicode编码的,储存一个char用16个bit,因此定义characters也是16位定长的实体集合. Unicode编码标准 ...

  9. vue 弹窗时 监听手机返回键关闭弹窗(页面不跳转)

    [注]:  popstate 事件 a.当活动历史记录条目更改时,将触发popstate事件. b.如果被激活的历史记录条目是通过对history.pushState()的调用创建的,或者受到对his ...

  10. C++ 驱动开发 error LNK2019

    最近在写一个机器人的时候,发现驱动无法编译通过.本文告诉大家如何解决这个问题. 在 VisualStudio 2017 15.8 的版本提供新的功能C++ Just My Code Stepping ...