传送门

$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. Codesign error: Certificate identity appearing twice

    第一种解决方法: I think I figured out why the simple delete is not working. Because the dev certificate is ...

  2. intellij idea怎么设置java帮助文档

    打开idea我引用的jar包都放在 Project Structure-->Modules-->libs文件夹(双击) 双击jar包所在文件夹,跳出对话框. 1.如果api对应的javad ...

  3. php第三方登录(微博登录,仿照慕课网)

    https://www.cnblogs.com/haoyu521/p/5606931.html 1:开发之前,请大家先自行熟悉一下OAuth协议原理. 2:我们开发需要具备一个外网可访问的线上域名,如 ...

  4. mysql数据库之存储引擎

    mysql存储引擎概述 什么是存储引擎?                                                               MYSQL中的数据用各不相同的技术 ...

  5. C++ 结构体的定义

    struct 结构体名称{    数据类型 A:    数据类型 B; }结构体变量名; 相当于: struct 结构体名称{    数据类型 A:    数据类型 B; }; struct 结构体名 ...

  6. behavior planning——13. implement a cost function in C++

    In the previous quizzes, you designed a cost function to choose a lane when trying to reach a goal i ...

  7. TP-admin即基于ThinkPHP5拿来即用高性能后台管理系统

    TP-Admin即基于ThinkPHP5的web后台管理系统(总结一套自己的后台管理系统,方便自己后续的项目开发.) 主要特性:自适应手机端.支持国际化.吸取其他CMF框架优点.多站点部署.日志记录. ...

  8. get_magic_quotes_gpc() PHP转义的真正含义

    如何正确的理解PHP转 义是一个初学者比较困扰的问题.我们今天为大家简要的讲述了PHP转义的具体含义,希望有所帮助.PHP转义一直困扰着我, 今天认真的看了一下PHP手册, 终于解决了. 在PHP中默 ...

  9. 如何利用aop的环绕消息处理log, 以及各种坑的记录

    如何利用aop的环绕消息处理log, 以及各种坑的记录 本文链接: https://www.cnblogs.com/zizaiwuyou/p/11667423.html 因为项目里有很多地方要打log ...

  10. 上传图片保存到MySql数据库并显示--经验证有效

    以下方法仅供参考,只是介绍下这一种方法而已.欢迎指正!! 前台(image.html):  1<html> 2<head> 3<title>上传图片</tit ...