Research on the longest common subsequence (LCS) and a series of DP issues

LIS problem:
set \ (f [i] \) is to (a [i] \) \ longest increased sequence length end with:
\ [F [I] = F [J] + 1'd (J <I && A [j] <a [i]
) \] can be used to optimize the array tree \ (O (nlogn) \)

LCS-based permutation problem ( \ (A, B \) are arranged, i.e. an element does not occur multiple times):
set \ (pos_i \) of \ (a_i \) in \ (B \) position appears, That \ (a_i = b_pos_i \) .
\ (A \) a subsequence \ (a_p_1, a_p_2, ..., a_p_m \) is \ (a, b \) common sub-sequence equivalent to \ (pos_p_1 <pos_p_2 <... <
pos_p_m \) seeking a LIS can be.

LCS general question:

  1. Classic Solution:
    set \ (f [i] [j ] \) represents only consider \ (A \) front \ (I \) th, \ (B \) front \ (J \) a longest common substring sequence length, there is:
    \ [F [I] [J] = \ left \ {\ the aligned the begin {} & F [. 1-I] [J-. 1] & A [I] B = [J] \\ & max (f [i-1] [ j], f [i] [j-1]) & a [i]! = b [j] \\ \ end {aligned} \ right. \]

Very simple, but there is a little more complex but expansion of higher approach:

设$f[i][j]$表示只考虑$a$中前$i$个,$b$中前$j$个并且$b_j$已经和$a_1,...,a_i$中的某一个匹配的最长公共子序列长度,有:

\ [f [i] [j ] = \ left \ {\ begin {aligned} & f [i-1] [j] & a [i]! = b [j] \\ & max (f [i-1 ] [k] +1) & a
[i] == b [j], k <j \\ \ end {aligned} \ right. \] why this expansion better? Look at this a question
to subject to the longest common subsequence rise, you can not use the classic solution of the LCS, but we think carefully about it directly and found that if we use the transfer equation above, we only need from \ (f [i-1 ] [K] \) was transferred to \ (f [i] [j ] \) , only the need to ensure \ (b [k] <b [j] \) to, so we get a new transfer equation:
\ [ f [i] [j] = \ \ {\ begin {aligned} & f [i-1] [j] & a [i] left! = b [j] \\ & max (f [i-1] [ k] +1) & a [i
] == b [j], k <j && b [k] <b [j] \\ \ end {aligned} \ right. \] and because when \ (a [i] = = b [j] \) when, \ (B [K] <B [J] \) is equivalent to \ (B [K] <A [I] \) , the transfer enumeration \ (J \) when All \ (b [k] <
Code:

#include<bits/stdc++.h>
using namespace std;
#define N 5007
int f[N],a[N],b[N];
int main()
{
    int i,j,n;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for(i=1;i<=n;i++)
        scanf("%d",&b[i]);
    int maxx=0,ans=0;
    for(i=1;i<=n;i++)
    {
        maxx=0;
        for(j=1;j<=n;j++)
        {
            if(b[j]==a[i])f[j]=max(f[j],maxx+1);
            else if(b[j]<a[i])maxx=max(maxx,f[j]);
            ans=max(ans,f[j]);
        }
    }
    printf("%d\n",ans);
    return 0;
}

Of course, for the average LCS problem \ (O (nlogn) \) solution (not strictly), the same can be extended to this problem, we first left the pit.

Guess you like

Origin www.cnblogs.com/lishuyu2003/p/11329708.html