P1439 模板 最長公共子串行 題解

2021-10-24 00:22:41 字數 2094 閱讀 1874

同步

原題鏈結

簡要題意:

給定兩個 1

11 ~ n

nn 的排列,求其最長公共子串行

嗯,下面給出若干演算法吧。

不管它是 1

11 ~ n

nn 的排列這一性質。

求 lcs

\text

lcs(即最長公共子串行)的套路方法:

用 f i,

jf_

fi,j

​ 表示 a

1a_1

a1​ ~ a

ia_i

ai​ 和 b

1b_1

b1​ ~ b

jb_j

bj​ 的最長公共子串行。那麼不考慮邊界問題,則存在:

f i,

j=

= \begin f_+ 1 , a_i = b_j \\ \max(f_ , f_) \end

fi,j​=

lcs 的求法,然後發現最優的 dp

\text

dp 就是 o(n

2)

o(n^2)

o(n2)?

但是注意到乙個性質 ,兩個陣列都是 1

11 ~ n

nn 的排列。

所以今天我們要秀出什麼操作呢!

5 

3 2 1 4 5

1 2 3 4 5

嗯,如果我們把3 2 1 4 5變成1 2 3 4 5,即建立一種關係為:

3 - 1

2 - 2

1 - 3

4 - 4

5 - 5

然後1 2 3 4 5它就變成了3 2 1 4 5(這純屬巧合啊)。

你發現,通過這樣一波操作,其實 lcs

\text

lcs 本質就是在 b

ib_i

bi​ 中找到若干個在 a

ia_i

ai​ 中有序出現的子串行。

顯然一波操作之後 a

ia_i

ai​ 有序,然後就是直接求 b

ib_i

bi​ 的 lis

\text

lis(最長上公升子串行)即可。因為任意的兩個 x

<

yx < y

x<

y 顯然對應的 a

ia_i

ai​ 也滿足有該序列。

時間複雜度:o(n

log⁡n)

o(n \log n)

o(nlogn)

.實際得分:100pt

s100pts

100pts

.

#pragma gcc optimize(2)

#include

using

namespace std;

const

int n=

1e5+1;

inline

intread()

int x=0;

while

(ch>=

'0'&& ch<=

'9') x=

(x<<3)

+(x<<1)

+ch-

'0',ch=

getchar()

;return x*f;

}int a2[n]

,a1[n]

,be[n]

;int b[n]

,f[n]

,ans,n;

intmain()

int t=

lower_bound

(b+1

,b+1

+ans,be[a2[i]])

-b; b[t]

=be[a2[i]

]; f[i]

=t;}

printf

("%d\n"

,ans)

;return0;

}

P1439 模板 最長公共子串行

給出1 n的兩個排列p1和p2,求它們的最長公共子串行。第一行是乙個數n,接下來兩行,每行為n個數,為自然數1 n的乙個排列。乙個數,即最長公共子串行的長度 輸入 1複製 5 3 2 1 4 5 1 2 3 4 5輸出 1複製 3 資料規模 對於50 的資料,n 1000 對於100 的資料,n 1...

P1439 模板 最長公共子串行

p1439 模板 最長公共子串行 這個題目我是沒想到反正我感覺十分的神奇先寫一下我在洛谷題解區看見的乙個很好理解的題解 對於樣例 3 2 1 4 5 1 2 3 4 5 我們可以把第乙個陣列編號位a b c d e 那麼第二個陣列就變成了c b a d e 現在對於第二個陣列的最長上公升子串行就是答...

P1439 模板 最長公共子串行

給出1 n的兩個排列p1和p2,求它們的最長公共子串行。輸入格式 第一行是乙個數n,接下來兩行,每行為n個數,為自然數1 n的乙個排列。輸出格式 乙個數,即最長公共子串行的長度 輸入樣例 1 複製 5 3 2 1 4 5 1 2 3 4 5 輸出樣例 1 複製 3 資料規模 對於50 的資料,n 1...