• P3402 最长公共子序列


    P3402 最长公共子序列
    经典问题
    LCS-->LIS

    没有重复的值才可以这么做
    把第一数列转化成1~n,然后将第二个数列映射成1~n中的一些数,然后求第二个数列的LIS即可,然后用Bit求LIS,O(nlogN)

    //数据太大,考虑map

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<algorithm>
    #include<cmath>
    #include<ctime>
    #include<map>
    #include<cstring>
    #define inf 2147483647
    #define For(i,a,b) for(register int i=a;i<=b;i++)
    #define p(a) putchar(a)
    #define g() getchar()
    //by war
    //2017.10.17
    using namespace std;
    int n,m;
    int t[300010];
    int ans;
    int f[300010];
    int a[300010];
    int b[300010];
    int x;
    map<int,int>c;
    void in(int &x)
    {
        int y=1;
        char c=g();x=0;
        while(c<'0'||c>'9')
        {
        if(c=='-')
        y=-1;
        c=g();
        }
        while(c<='9'&&c>='0')x=x*10+c-'0',c=g();
        x*=y;
    }
    void o(int x)
    {
        if(x<0)
        {
            p('-');
            x=-x;
        }
        if(x>9)o(x/10);
        p(x%10+'0');
    }
    
    int getmax(int k)
    {
        int Max=0;
        for(;k>0;k-=(-k)&k)
        Max=max(Max,t[k]);
        return Max;
    }
    
    void modify(int k,int Max)
    {
        for(;k<=n;k+=(-k)&k)
        t[k]=max(t[k],Max);
    }
    
    int main()
    {
        in(n),in(m);
        For(i,1,n)
        in(b[i]),c[b[i]]=i;
        For(i,1,m)
        in(a[i]);
        For(i,1,m)
        a[i]=c[a[i]];
        For(i,1,m)
        {
            f[i]=getmax(a[i])+1;
            ans=max(ans,f[i]);
            if(a[i]>0)
            modify(a[i],f[i]);
        }
        o(ans);
         return 0;
    }
    View Code

    我今天才算搞懂最长公共子序列的nlogn的做法,下面的是任何情况都适用的

    5 4 1 1 2
    1 2 4,3 4,3 5

    1 1 4
    4 3 4 3 5

    在4 3 4 3 5里面求严格递增的LIS就是二者的LCS

    #include <bits/stdc++.h>
    #define inf 2147483647
    #define N 1000010
    #define p(a) putchar(a)
    #define For(i,a,b) for(long long i=a;i<=b;++i)
    //by war
    //2020.4.24
    using namespace std;
    long long n,m,cnt;
    long long t[N],a[N],b[N],temp[N];
    long long ans0,ans1;
    long long x;
    map<long long,long long>c,d;
    vector<long long>v[N],u;
    stack<int>st;
    void in(long long &x){
        long long y=1;char c=getchar();x=0;
        while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
        while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();}
        x*=y;
    }
    void o(long long x){
        if(x<0){p('-');x=-x;}
        if(x>9)o(x/10);
        p(x%10+'0');
    }
    
    long long getmax(long long k){
        long long Max=0;
        for(;k>0;k-=(-k)&k) 
            Max=max(Max,t[k]);
        return Max;
    }
    
    void modify(long long k,long long Max){
        for(;k<=cnt;k+=(-k)&k)
              t[k]=max(t[k],Max);
    }
    
    signed main(){
        in(n);in(m);
        For(i,1,n){
            in(b[i]);
            if(c[b[i]]==0){
                c[b[i]]=i;
                v[i].push_back(i);
            }
            else v[c[b[i]]].push_back(i);
            temp[i]=b[i];
        }
        sort(temp+1,temp+n+1);
        For(i,1,n) d[temp[i]]=i;
        For(i,1,n) b[i]=d[b[i]],u.push_back(b[i]);
        cnt=u.size();
        for(auto i:u){
            long long cc=getmax(i-1)+1;
            ans0=max(ans0,cc);
            modify(i,cc);
        }
        u.clear();
        For(i,1,m) in(a[i]);
        For(i,1,m){
            if(c[a[i]]!=0){
                for(auto j:v[c[a[i]]])
                    st.push(j);
                while(!st.empty()) u.push_back(st.top()),st.pop();
            }
        }
        memset(t,0,sizeof(t));
        for(auto i:u){
            long long cc=getmax(i-1)+1;
            ans1=max(ans1,cc);
            modify(i,cc);
        }
        o(ans0);p(' ');o(ans1);
        return 0;
    }
  • 相关阅读:
    RabbitMQ 工作图解
    RabbitMQ常用命令
    搭建 .Net RabbitMQ 开发环境
    不使用第三个变量交换两个变量的值
    WEB编程 入门简单 进阶难
    C# 字符串的长度问题
    C# 反射
    C# 拼接字符串的几种方式和性能
    ASP.NET MVC 教程汇总
    SSIS中循环遍历组件[Foreach Loop Container]
  • 原文地址:https://www.cnblogs.com/war1111/p/7682443.html
Copyright © 2020-2023  润新知