$ZOJ\ 2432\ Greatest\ Common\ Increasing\ Subsequence$
$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 ;
}
随机推荐
- 根据花瓶的侧面投影图,用Matlab绘制花瓶的三维立体图
现有一花瓶侧面投影如图 问题: 1) 做出该花瓶三维立体图: 2) 计算其表面积: 计算其体积. 第一次参加数学建模,从来没有接触过Matlab语言,一上来就碰到这种数字图像处理的问题就 ...
- BT17破解软件
大家好我QQ是1617089375 有非常多网友非常好奇新版BT17无线网破解软件究竟怎么样.无图无真相,所以我上传给大家看看,眼下视频正在录制.稍后也会把相应的视频公布到网上.因为 ...
- linux内核分析笔记----中断和中断处理程序
中断还是中断,我讲了很多次的中断了,今天还是要讲中断,为啥呢?因为在操作系统中,中断是必须要讲的.. 那么什么叫中断呢, 中断还是打断,这样一说你就不明白了.唉,中断还真是有点像打断.我们知道linu ...
- uni-app获取dom元素到顶部的距离以及操作dom元素的一些样式
一. 1.首先有一个元素 <view class="activity" ref="btn"></view> 2.确认指针指向 this. ...
- day1_python之字符串的常用操作
python字符串操作常用操作,如字符串的替换.删除.截取.复制.连接.比较.查找.分割等,需要的朋友可以参考下. 1.去除空格 str.strip():删除字符串两边的指定字符,括号的写入指定字符, ...
- Element-ui学习笔记3--Form表单(一)
Radio单选框 要使用 Radio 组件,只需要设置v-model绑定变量,选中意味着变量的值为相应 Radio label属性的值,label可以是String.Number或Boolean. & ...
- Python--day67--Jsonresponse响应介绍和路由系统的分组命名匹配方式(简单介绍)
1,Jsonresponse响应介绍: ,2,路由系统的分组命名匹配方式:(简单介绍)
- Python--day30--tcp协议(建立链接三次握手,断掉链接四次挥手)和UDP协议
TCP协议: tcp是可靠的,面向连接的.建立全双工通信. 建立链接的三次握手 链接一旦建立一定是全双工工通信,必然是双方通信. UDP协议: TCP协议和UDP协议的对比: QQ使用的是UDP,因为 ...
- Vue 语法的一些小问题
设置 sty行内样式 :style="{width:mapWidth,height:mapHeight}" This指向 axios 使用axios 的时候 ,在生命周期函数 ...
- git提交时如何忽略一些文件
起因 在使用git对软件进行版本管理的时候我们总有一些不需要提交到版本库里的文件和文件夹,或者在管理一个实际应用的开源项目的时候,不可以把带有数据库信息的文件上传到开源平台当中,这个时候我们就需要让g ...