標籤:bzoj bzoj1264 動態規劃 樹狀數組 lcs
題目大意:給定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 200200using 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;}
BZOJ 1264 AHOI2006 基因匹配Match 動態規劃+樹狀數組