P1439 [Template] Solutions to the longest common subsequence

CSDN synchronization

Original title link

Brief title:

Given two (. 1 \) \ ~ \ (n-\) are arranged, find the longest common subsequence .

Well, here are some algorithms.

Algorithm One

It doesn't matter whether it is \ (1 \) ~ \ (n \) arrangement.

Find the routine of \ (\ text {LCS} \) (that is, the longest common subsequence):

Use \ (f_ {i, j} \) to represent the longest common subsequence of \ (a_1 \) ~ \ (a_i \) and \ (b_1 \) ~ \ (b_j \) Then without considering the boundary problem, there are:

\[f_{i,j} = \begin{cases} f_{i-1,j-1}+ 1 , a_i = b_j \\ \max(f_{i,j-1} , f_{i-1,j}) \end{cases}\]

Obviously, if the current bits are equal, they will shrink together, otherwise, they will shrink.

Time complexity: \ (O (n ^ 2) \) .

Actual score: \ (50pts \) .

Algorithm two

Well, you went to Baidu and searched for the method of \ (\ text {LCS} \) , and found that the optimal \ (\ text {dp} \) is \ (O (n ^ 2) \) ?

But note a property, both arrays are \ (1 \) ~ \ (n \) arrangement.

So what are we going to show today?

5 
3 2 1 4 5
1 2 3 4 5

Ah, if we 3 2 1 4 5become 1 2 3 4 5, namely the establishment of a relationship is:

3 - 1
2 - 2
1 - 3
4 - 4
5 - 5

Then 1 2 3 4 5it becomes a 3 2 1 4 5(ah this is purely coincidental).

You found that by operating such a wave, in fact, \ (\ text {LCS} \ ) is essentially in \ (b_i \) found in a number of \ (a_i \) sequences in order of appearance.

Obviously wave operation after the \ (a_i \) order, and then is determined directly \ (B_i \) a \ (\ text the LIS} {\) (longest rising sequence) can. Because any two \ (x <y \) obviously correspond to \ (a_i \) also satisfy the sequence.

Time complexity: \ (O (n \ log n) \) .

Actual score: \ (100pts \) .

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;

const int N=1e5+1;

inline int read(){char ch=getchar();int f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
	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;

int main(){
	n=read(); for(int i=1;i<=n;i++)
		a1[i]=read(),be[a1[i]]=i; //建立对应关系
	for(int i=1;i<=n;i++) a2[i]=read();
	for(int i=1;i<=n;i++) {
		if(be[a2[i]]>b[ans]) { //正常套路 LIS
			b[++ans]=be[a2[i]]; f[i]=ans; continue;
		} 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);
	return 0;
}

Guess you like

Origin www.cnblogs.com/bifanwen/p/12676102.html