bzoj 1264: [AHOI2006]基因匹配Match (树状数组优化dp)
2023-11-17 10:57:46
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1264
思路: n大小为20000*5,而一般的dp求最长公共子序列复杂度是 n*n的,所以我们必须优化。
题目说了一个数会出现5次,那么我们可以预处理得到 第一个序列a[]每个数字分别在哪些位置,
因为求LCS的状态转移方程中当 s1[i-1] == s2[j-1]时,dp[i][j] = dp[i-1][j-1] + 1;只有当两个点相同时
值才会+1,我们可以对第二个序列b[]遍历一遍,对于b[i]我们可以找到它在a[]上的5个位置,这5个
位置的dp[pos]都可以被更新,状态转移方程为: dp[pos] = max(p[1] - p[pos-1]) + 1, 对于dp[1] - dp[pos],
这段区间的最大值,我们直接用树状数组维护就好了,时间复杂度为 O(n*logn)
实现代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long const int M = 2e5+;
int a[M][],c[M],dp[M],n; void update(int x,int p){
while(x <= n*){
c[x] = max(c[x],p);
x += (x&-x);
}
} int getsum(int x){
int ans = ;
while(x){
ans = max(ans,c[x]);
x -= (x&-x);
}
return ans;
} int main()
{
int x;
cin>>n;
for(int i = ;i <= n*;i ++){
cin>>x;
a[x][++a[x][]] = i;
}
for(int i = ;i <= n*;i ++){
cin>>x;
for(int j = ;j >= ;j --){
int num = getsum(a[x][j]-)+;
if(num > dp[a[x][j]]) dp[a[x][j]] = num,update(a[x][j],num);
}
}
int ans = ;
for(int i = ;i <= n*;i ++){
ans = max(dp[i],ans);
}
cout<<ans<<endl;
return ;
}
最新文章
- jquery手风琴
- Linux网络编程系列-TCP传输控制
- 【URAL 1486】Equal Squares
- udp通信的原理---makefile文件
- 火狐的打开3D效果
- jquery.ajax和Ajax 获取数据
- SQL Server IO系统问题解决
- struts2中使用ognl表达式时各种符号的使用规则$,#,%
- Apache 服务器
- hdu 2191 (多重背包+二进制优化)
- C#调用PB写的com组件dll
- ZOJ 3811 Untrusted Patrol The 2014 ACM-ICPC Asia Mudanjiang Regional First Round
- 利用angularJs自定义指令(directive)实现在页面某一部分内滑块随着滚动条上下滑动
- mybatise插入返回主键ID
- (六)SpringBoot2.0基础篇- Redis整合(JedisCluster集群连接)
- 在IIS上新发布的网站,样式与js资源文件加载不到(资源文件和网页同一个域名下)
- Steps to One DP+莫比乌斯反演
- 微信小程序里的bug---video 的play()
- hibernate框架学习之数据抓取(加载)策略
- ThinkPHP框架 表单传值自动验证!!