zoukankan      html  css  js  c++  java
  • NYIST 760 See LCS again

    See LCS again
    时间限制:1000 ms | 内存限制:65535 KB
    难度:3


    描述
    There are A, B two sequences, the number of elements in the sequence is n、m;

    Each element in the sequence are different and less than 100000.

    Calculate the length of the longest common subsequence of A and B.

    输入
    The input has multicases.Each test case consists of three lines;
    The first line consist two integers n, m (1 < = n, m < = 100000);
    The second line with n integers, expressed sequence A;
    The third line with m integers, expressed sequence B;

    输出
    For each set of test cases, output the length of the longest common subsequence of A and B, in a single line.


    样例输入
    5 4
    1 2 6 5 4
    1 3 5 4


    样例输出
    3


    上传者
    TC_胡仁东

    解题:一种LCS转LCS的nlogn的算法。是严格上升的LCS。

    首先是LCS,我们把a序列中的每个元素在b中出现的位置保存起来,再按照降序排列,排列后再代入a的每个对应元素,那就转化为了求这个新的序列的最长上升子序列了。如:a[] = {a, b, c,} b[] = {a,b,c,b,a,d},那么a中的a,b,c在b中出现的位置分别就是{0,4},{1,3},{2}。分别按降序排列后代入a序列就是{4,0,2,3,1},之所以要按照降序排列,目的就是为了让每个元素只取到一次。

    接下来的问题就是要求最长升序子序列问题了,也就是求LIS。

     特殊情况下,会退化得很严重。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 #include <climits>
     7 #include <vector>
     8 #include <queue>
     9 #include <cstdlib>
    10 #include <string>
    11 #include <set>
    12 #include <stack>
    13 #define LL long long
    14 #define pii pair<int,int>
    15 #define INF 0x3f3f3f3f
    16 using namespace std;
    17 struct info{
    18     int num,pos;
    19 };
    20 int n,m,tot,sa[100010],sc[200010],q[200010],head,tail;
    21 info sb[100010];
    22 bool cmp(const info &x,const info &y){
    23     return x.num < y.num;
    24 }
    25 int bsearch(int lt,int rt,int val){
    26     int mid,pos = -1;
    27     while(lt <= rt){
    28         int mid = (lt+rt)>>1;
    29         if(val <= sb[mid].num){
    30             pos = mid;
    31             rt = mid-1;
    32         }else lt = mid+1;
    33     }
    34     return pos;
    35 }
    36 int binsearch(int lt,int rt,int val){
    37     while(lt <= rt){
    38         int mid = (lt+rt)>>1;
    39         if(q[mid] < val) lt = mid+1;
    40         else rt = mid-1;
    41     }
    42     return lt;
    43 }
    44 int main() {
    45     while(~scanf("%d %d",&n,&m)){
    46         head = tail = tot = 0;
    47         for(int i = 1; i <= n; i++) scanf("%d",sa+i);
    48         for(int i = 1; i <= m; i++){
    49             scanf("%d",&sb[i].num);
    50             sb[i].pos = i;
    51         }
    52         sort(sb+1,sb+m+1,cmp);
    53         for(int i = 1; i <= n; i++){
    54             int tmp = bsearch(1,m,sa[i]);
    55             while(tmp > 0 && sb[tmp].num == sa[i]) sc[tot++] = sb[tmp++].pos;
    56         }
    57         for(int i = 0; i < tot; i++){
    58             if(head == tail || q[head-1] < sc[i]){
    59                 q[head++] = sc[i];
    60             }else{
    61                 int tmp = binsearch(tail,head-1,sc[i]);
    62                 q[tmp] = sc[i];
    63             }
    64         }
    65         printf("%d
    ",head-tail);
    66     }
    67     return 0;
    68 }
    View Code
  • 相关阅读:
    底部菜单栏之Fragment的详细介绍和使用方法
    Warm up 2
    如何做好一位资深的web前端工程师
    使用 HTML5 canvas 绘制精美的图形
    计算元素距离浏览器左边的距离
    [JSOI2016]独特的树叶
    【SDOI2009】Elaxia的路线
    【SCOI2009】最长距离
    【SCOI2009】围豆豆
    【AHOI2005】穿越磁场
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/3960720.html
Copyright © 2011-2022 走看看