• 洛谷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≤100000

    ****复杂度为nlogn哦,离散化,然后求最长上升序列

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<algorithm>
     5 using namespace std;
     6 int i,j,n,a[100005],b[100005],ans,c[100005],f[100005];
     7 int main()
     8 {
     9     scanf("%d",&n);
    10     for(i = 1;i <= n;i++)
    11     {
    12         scanf("%d",&a[i]);
    13         c[a[i]] = i; //用于离散化 
    14     }
    15     for(i = 1;i <= n;i++)
    16     {
    17         scanf("%d",&b[i]);
    18         f[i] = 0x7ffffff;
    19     }
    20     f[0] = 0;
    21     ans = 0;
    22     for(i = 1;i <= n;i++)
    23     {
    24         int l = 0,r = ans,mid;
    25         if(c[b[i]] > f[ans]) //求最大上升子序列 
    26         {
    27             ans++;
    28             f[ans] = c[b[i]];
    29         }
    30         else
    31         {
    32             while(l < r)
    33             {
    34                 mid = (l + r) / 2;
    35                 if(f[mid] > c[b[i]])
    36                 r = mid;
    37                 else
    38                 l = mid + 1;
    39             }
    40             f[l] = min(f[l],c[b[i]]); // 求最大上升子序列长度为l时的最后一个值越小越好 
    41         }
    42     }
    43     printf("%d",ans);
    44     return 0;
    45 }
  • 相关阅读:
    POJ 3292 Semi-prime H-numbers (素数筛法变形)
    POJ 1845 Sumdiv (整数拆分+等比快速求和)
    POJ 2635 The Embarrassed Cryptographer(大数求余)
    POJ 2115 C Looooops (扩展欧几里德 + 线性同余方程)
    poj3071
    poj2486
    poj1947
    POJ 1159
    POJ 1845
    poj3282
  • 原文地址:https://www.cnblogs.com/rax-/p/9934249.html
Copyright © 2020-2023  润新知