洛谷P3402 最長公共子串行

2021-08-05 23:12:09 字數 1626 閱讀 4019

題目背景

djl為了避免成為乙隻鹹魚,來找johann學習怎麼求最長公共子串行。

題目描述

經過長時間的摸索和練習,djl終於學會了怎麼求lcs。johann感覺djl孺子可教,就給他布置了乙個課後作業:

給定兩個長度分別為n和m的序列,序列中的每個元素都是正整數。保證每個序列中的各個元素互不相同。求這兩個序列的最長公共子串行的長度。

djl最討厭重複勞動,所以不想做那些做過的題。於是他找你來幫他做作業。

輸入輸出格式

輸入格式:

第一行兩個整數n和m,表示兩個數列的長度。

第二行一行n個整數a_1,a_2,…,a_n,保證1≤a_i≤〖10〗^9。

第三行一行m個整數b_1,b_2,…,b_m,保證1≤b_i≤〖10〗^9。

輸出格式:

一行乙個整數,表示兩個數列的最長公共子串行的長度。

輸入輸出樣例

輸入樣例#1:

6 6

1 3 5 7 9 8

3 4 5 6 7 8

輸出樣例#1:

4 說明

對於40%的資料,n, m≤3000

對於100%的資料,n, m≤300000

【題解】

為什麼前面的神牛都用了stl函式upper——bound,我這個小蒟蒻不懂。。。

於是乎,我寫了個沒用這個stl函式的**,速度慢到爆(最後乙個點0.9s+)。

此題難點是

1、資料範圍過大,這需要用不定長陣列map(不懂看度娘)

2、此題資料是用來卡ac的,所以要先將其轉化為乙個子串行(map的對映功能),再用優化演算法——lis的n*logn演算法。

3、lis的n*logn演算法:d[i]保留滿足f[i] = k的所有a[i]中的最小值。f[i]表示從1到i這一段中以i結尾的最長上公升子串行的長度。設當前已經求出的最長上公升子串行長度為len。先判斷a[i](乙個子串行)與d[len],若a[i] > d[len],則將a[i]接在d[len]後將得到乙個更長的上公升子串行,len = len + 1,d[len+1] = a[i];否則,在d[1]..d[len]中,找到最大的j,滿足d[j] < a[i].令k = j + 1,則有d[j] < a[i] <= d[k],將a[i]接在d[j]後將得到乙個更長的上公升子串行,同時更新d[k] = a[i].最後,len即為所要求的最長上公升子串行的長度。

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

mapf;//不定長陣列,相當於一種對映,具體請問度娘

int a[300009]={},n,m,c[400009]={},d[260000]={},aa,bb;

int lcs()

d[l]=c[i];

if(l>t)//如果發現找出的位置在最後面,那就加長度

t++;

}return t;

}int main()

int ans=lcs();//lis的n*logn演算法

cout

0;}

P3402 最長公共子串行

p3402 最長公共子串行 經典問題 lcs lis 沒有重複的值才可以這麼做 把第一數列轉化成1 n,然後將第二個數列對映成1 n中的一些數,然後求第二個數列的lis即可,然後用bit求lis,o nlogn 資料太大,考慮map include include include include i...

P3402 最長公共子串行(nlogn)

先看一下資料規模 n 300000,n 2的做法肯定就要掛掉了,所以用到了這個nlogn的做法。先介紹一下nlogn的做法 最長公共子串行 的 nlogn 的演算法本質是 將該問題轉化成 最長增序列 lis 因為 lis 可以用nlogn實現,所以求lcs的時間複雜度降低為 nlogn。轉化 將lc...

洛谷 P1439 最長公共子串行

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