洛谷1439 模板 最長公共子串行

2021-08-18 02:28:54 字數 1105 閱讀 7256

題目:最長公共子串行

思路:這題用一般的dp來做,f( i , j )表示a的前i位和b的前j位的最長公共子串行的長度,時間複雜度為o(n^2),在這題會tle。

在這題中,需要用o(nlogn)的複雜度實現。

先設計乙個陣列b,b[i]代表b串中的數第i個數在a串中的位置。例如:

a串: 3 2 1 4 5

b串: 5 4 3 2 1

b[ ]: 5 4 1 2 3

這時,求ab兩串的最長公共子串行也就是求b的最長上公升子串行。因為乙個序列x是ab的共共子串行,當且僅當x中的每乙個數對應在ab兩串的位置,都小於下乙個數在ab兩串中對應的位置。也就是說,x的每乙個數在ab兩串中對應的位置都是遞增的。

b陣列的設定就是相當於把a排了序,使a中的數遞增,那麼要是b中的數遞增,就需要求b的上公升子串行。

求最長上公升子串行的樸素的dp做法的複雜度也是o(n^2),但是可以用二分優化成o(nlogn)。

令f[x]表示b中最長上公升子串行為x時序列的最後乙個數的最小值。可以利用貪心的思想得到,每遍歷到乙個數b[i]時,f[x]=min(b[i],f[x]),其中x等於取乙個最大的j使得f[j]的值小於b[i]的f[j]的值。由於f的值一定是有序的,所以求這個值就可以二分了。

注意這裡的二分寫的是stl庫中的 lower_bound 函式。

**:

#includeusing namespace std;

#define maxn 100000

int n;

int a[maxn+5]=,b[maxn+5]=;

int f[maxn+5]=;

int main()

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

for(int i=2;i<=n;i++) f[i]=(1<<30);

f[1]=b[1],f[0]=0;

int len=1;

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

int x=lower_bound(f+1,f+len+1,b[i])-f;

f[x]=min(b[i],f[x]);

} printf("%d",len);

return 0;

}

洛谷 1439 最長公共子串行

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

洛谷 P1439 模板 最長公共子串行

lis lcs 對映 題目描述 給出1 n的兩個排列p1和p2,求它們的最長公共子串行。輸入輸出格式 輸入格式 第一行是乙個數n,接下來兩行,每行為n個數,為自然數1 n的乙個排列。輸出格式 乙個數,即最長公共子串行的長度 輸入輸出樣例 輸入樣例 1 5 3 2 1 4 5 1 2 3 4 5 輸出...

洛谷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 對於1...