$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 ;
}
随机推荐
- 使用jQuery的 autocomplete 实现输入框 自动提示补全
参考网址: https://www.cnblogs.com/jinzhiming/p/6768402.html 插件下载地址: 链接:https://pan.baidu.com/s/1SpP3hixZ ...
- SDUT-2131_数据结构实验之栈与队列一:进制转换
数据结构实验之栈与队列一:进制转换 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 输入一个十进制非负整数,将其转换成对 ...
- Python基础:24with语句
一:with语句 在Python 2.6 中正式引入的with语句,是用来简化代码的.这与用try-except 和try-finally所想达到的目的前后呼应.try-except 和try-fin ...
- mysql 优化 1
一. 数据库索引 规则8:业务需要的相关索引是根据实际的设计所构造sql语句的where条件确定的,业务不需要的不要建索引,不允许在联合索引(或主键)中存在多余的字段,特别是该字段根本不会在条件语句中 ...
- oracle使用TKPROF 工具来查询SQL性能状态
SQL trace 工具收集正在执行的SQL的性能状态数据并记录到一个跟踪文件中. 这个跟踪文件提供了许多有用的信息,例如解析次数.执行次数,CPU使用时间等.这些数据将可以用来优化你的系统. 设置S ...
- ras 加解密类,支持截取
class RsaEncrypt{ private $_privateKey = false; private $_publicKey = false; /** * 私钥解密 * @param $da ...
- 字符串编辑距离(Edit Distance)
一.问题描述定义字符串编辑距离(Edit Distance),是俄罗斯科学家 Vladimir Levenshtein 在 1965 年提出的概念,又称 Levenshtein 距离,是指两个字符串之 ...
- Laravel 修改默认日志文件名称和位置
修改默认日志位置 我们平常的开发中可能一直把laravel的日志文件放在默认位置不会有什么影响,但如果我们的项目上线时是全量部署,每次部署都是git中最新的代码,那这个时候每次都会清空我们的日志,显示 ...
- ip2long与long2IP 分析
<?php $ip='47.93.97.127'; $long=sprintf("%u",ip2long($ip));//string(9) "794648959& ...
- 小程序clearinterval无效解决
小程序clearinterval无效解决 小程序clearinterval清除定时器无效,原因是定时器使用与清除方法不对导致的,我们应将定时器绑定变量,这样在关闭页面清空定时器clearinterva ...