zoukankan      html  css  js  c++  java
  • 洛谷 P1439【模板】最长公共子序列

    神TM模板。。我本来想休闲一下写点水题的。。。

    开始做的时候直接敲了一个O(N2)的算法上去,编译的时候才发现根本开不下。。

    好了,谈回这道题。

    先不加证明的给出一种算法。

    若有一组数据
    2
    4 2 5 1 3
    2 5 4 1 3
    那么我们令
    4 2 5 1 3
    | | | | |
    1 2 3 4 5
    第三行的数据就变成
    2 3 1 4 5
    很明显,答案是这个数据的最长上升子序列,即4 == 2 3 4 5,即原数列的2 5 1 3。

    现在来大概的介绍一下这样做的原因。

    首先,观察题目,注意到这个题和真正的模板的区别:给出1-n的两个排列P1和P2。

    思考排列的性质,及从1-N的每个数会且仅会出现一次。

    引用洛谷题解中一句话:

    因为最长公共子序列是按位向后比对的,所以a序列每个元素在b序列中的位置如果递增,就说明b中的这个数在a中的这个数整体位置偏后,可以考虑纳入LCS——那么就可以转变成nlogn求用来记录新的位置的map数组中的LIS

    于是即可写出代码。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int MAXN = 1e5 + 20;
     4 const int INF = 0x3f3f3f3f;
     5 
     6 inline int read()
     7 {
     8     int x = 0; char ch = getchar();
     9     while(!isdigit(ch)) ch = getchar();
    10     while(isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
    11     return x;
    12 }
    13 
    14 int N;
    15 int a[MAXN], f[MAXN];
    16 
    17 int main()
    18 {
    19     cin>>N;
    20     for(int i = 1; i <= N; i++)
    21         a[read()] = i;
    22 
    23     memset(f, 0x3f, sizeof(f));
    24     int cur;
    25     for(int i = 1; i <= N; i++)
    26     {
    27         cur = a[read()];
    28         *lower_bound(f, f + N + 1, cur) = cur;
    29     }
    30 
    31     cout<<(lower_bound(f, f + N + 1, INF) - f)<<endl;
    32     return 0;
    33 }

     

  • 相关阅读:
    Beego快速入门
    Ubuntu常用配置
    软件过程改进练习题
    将博客搬至CSDN
    【PTA】04-树4 是否同一棵二叉搜索树
    【PTA】03-树1 树的同构
    【转】面试还搞不懂redis,快看看这40道Redis面试题(含答案和思维导图)
    数据挖掘--聚类算法对比
    数据挖掘--模型挖掘之聚类
    数据挖掘--OPTICS
  • 原文地址:https://www.cnblogs.com/wsmrxc/p/8972481.html
Copyright © 2011-2022 走看看