BZOJ 1264 基因匹配 DP 線段樹

2022-05-26 23:39:10 字數 1913 閱讀 8972

很有意思的一道題啊。

求兩個序列的最大公共子串行。保證每個序列中含有1-n各5個。

如果直接lcs顯然是tle的。該題與普通的lcs不同的是每個序列中含有1-n各5個。

考慮lcs的經典dp方程。dp[i][j]=dp[i-1][j-1]+1.(a[i]==b[j])。 dp[i][j]=max(dp[i-1][j],dp[i][j-1]).(a[i]!=b[j])。

如果換個角度看看。令dp[i][j]表示a序列以i結尾,b序列到j的最大公共子串行長度。

則有dp[i][j]=max(dp[k][j])+1.(a[i]==b[j]&&k如果從b序列從左向右更新狀態的話。第乙個轉移就是求字首最大值。第二個轉移實際就是不變。

因此維護乙個線段樹即可。

# include # include 

# include

# include

# include

# include

# include

# include

# include

# include

# include

using

namespace

std;

# define lowbit(x) ((x)&(-x))

# define pi acos(-1.0

)# define eps 1e-9

# define mod

1000000000

# define inf

1000000000

# define mem(a,b) memset(a,b,

sizeof

(a))

# define for(i,a,n)

for(int i=a; i<=n; ++i)

# define fo(i,a,n)

for(int i=a; ii)

# define bug puts("h

");# define lch p

<<1

,l,mid

# define rch p

<<1|1,mid+1

,r# define mp make_pair

# define pb push_back

typedef pair

pii;

typedef vector

vi;# pragma comment(linker,

"/stack:1024000000,1024000000")

typedef

long

long

ll;int

scan()

while(ch>='

0'&&ch<='9')

return x*f;

}void out(int

a)

if(a>=10) out(a/10

); putchar(a%10+'0'

);}const

int n=20005;//

code begin...

int a[n*5], b[n*5], vis[n][6], cnt[n], seg[n*20

];void push_up(int p)

int query(int p, int l, int r, int

r)void update(int p, int l, int r, int l, int

val)

}int

main ()

for(i,

1,n*5

) }

printf(

"%d\n

",query(1,1,n*5,n*5

));

return0;

}

view code

AHOI2006 bzoj1264 基因匹配

description 基因匹配 match 卡卡昨天晚上做夢夢見他和可可來到了另外乙個星球,這個星球上生物的dna序列由無數種鹼基排列而成 地球上只有4種 而更奇怪的是,組成dna序列的每一種鹼基在該序列中正好出現5次!這樣如果乙個dna序列有n種不同的鹼基構成,那麼它的長度一定是5n。卡卡醒來後...

特殊位置kmp匹配 bzoj4641 基因改造

傳送門!將每個數變成當前位置減上一次出現的位置,用kmp kmpkm p匹配,但要注意如果當前位置減上一次出現位置的差超過了匹配長度則視為沒有出現過,要特判 include include include include include define maxn 1000005 define ll l...

BZOJ3039 玉蟾宮(懸線dp 單調棧)

description 有一天,小貓rainbow和freda來到了湘西張家界的天門山玉蟾宮,玉蟾宮宮主藍兔盛情地款待了它們,並賜予它們一片土地。這片土地被分成n m個格仔,每個格仔裡寫著 r 或者 f r代表這塊土地被賜予了rainbow,f代表這塊土地被賜予了freda。現在freda要在這裡賣...