BZOJ 1264 AHOI2006 基因匹配Match 动态规划+树状数组

题目大意:给定n个数和两个长度为n*5的序列,每一个数恰好出现5次,求两个序列的LCS

n<=20000。序列长度就是10W。朴素的O(n^2)一定会超时

所以我们考虑LCS的一些性质

LCS的决策+1的条件是a[i]==b[j] 于是我们记录a序列中每一个数的5个位置

扫一下b[i] 对于每一个b[i]找到b[i]在a中的5个位置 这5个位置的每一个f[pos]值都能够被b[i]更新 于是找到f[1]到f[pos-1]的最大值+1 更新f[pos]就可以

这个用树状数组维护 时间复杂度O(nlogn)

非常难想的一道题 只是不难写

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define M 200200
using namespace std;
int n,ans,a[M*5],b[M*5],c[M*5],f[M*5],pos[M][6];
void Update(int x,int y)
{
	for(;x<=n*5;x+=x&-x)
		c[x]=max(c[x],y);
}
int Get_Ans(int x)
{
	int re=0;
	for(;x;x-=x&-x)
		re=max(re,c[x]);
	return re;
}
int main()
{
	int i,j;
	cin>>n;
	for(i=1;i<=n*5;i++)
	{
		scanf("%d",&a[i]);
		pos[ a[i] ][ ++pos[a[i]][0] ]=i;
	}
	for(i=1;i<=n*5;i++)
		scanf("%d",&b[i]);
	for(i=1;i<=n*5;i++)
	{
		for(j=5;j;j--)
		{
			int k=pos[b[i]][j];
			f[k]=max( f[k] , Get_Ans(k-1)+1 );
			Update(k,f[k]);
			ans=max(ans,f[k]);
		}
	}
	cout<<ans<<endl;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值