題意:給你兩個長度為n(n<=1e5)的排列,求兩個排列的最長公共子串行。
樸素lcs(最長公共子串行):對於時間複雜度為o(n^2)的樸素lcs,我們用二維陣列f[i][j]表示第乙個序列的前i個和第二個序列的前j個,他們的最長公共子串行的長度,那麼狀態轉移方程:a[i]==b[j]:dp[i][j]=dp[i-1][j-1]+1else:dp[i][j]=max(dp[i-1][j],dp[i][j-1])。
但是這題很明顯,時間和空間複雜度都不符合要求,但是這題是對於兩個長度相同的排列,我們只需要在把第二個排列的每個數轉化為它在另乙個排列中的位置,再求第二個排列的最長上公升子串行(o(nlogn)可求)就行。(自己想想,挺好懂的 )
樸素方法:
int a[n]
,b[n]
,dp[n]
[n];
signed
main()
} cout<[n]<}
本題ac**:
#include
#define endl '\n'
#define null null
#define ls p<<1
#define rs p<<1|1
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define ll long long
#define int long long
#define vi vector
#define mii map
#define pii pair
#define ull unsigned long long
#define all(x) x.begin(),x.end()
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ct cerr<<"time elapsed:"<<1.0*clock()/clocks_per_sec<<"s.\n";
char
*fs,
*ft,buf[
1<<20]
;#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
inline
intread()
while
(ch>=
'0'&&ch<=
'9')
return x*f;
}using
namespace std;
const
int n=
1e5+5;
const
int inf=
0x7fffffff
;const
int mod=
998244353
;const
double eps=
1e-6
;const
double pi=
acos(-
1);int a[n]
,b[n]
,c[n]
,d[n]
;signed
main()
for(
int i=
1;i<=n;i++
)int len=1;
d[1]
=b[1];
for(
int i=
1;i<=n;i++
) cout<}
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...