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

    许久没有刷题,认为一个小学生教练到了普及一等的水平就可以安稳的睡了。孩子们外出上学的梦想湮灭。想传出去的球又回来了,孩子水平高了很多,我安心的看着他们进步。弊端逐渐显露,没有人带领,他们总是陷入各种迷茫。这种带领不一定是知识上的,也许就是精神上的,那么我也重新打开两年前的刷题暂停键,陪伴他们一起前行。

    这道题非常神奇。对于一个有着简单背包、线性动态规划基础的中年人来说非常的虐。

    首先,我是这样写的。

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int a[100000],b[100000];
    int f[10000][10000];
    int main()
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&b[i]);
        }
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        {
            
            if(a[i]==b[j])
            {
                f[i][j]=max(f[i][j],f[i-1][j-1]+1);
            }
            else
            {
                f[i][j]=max(f[i-1][j],f[i][j-1]);
            }
        }
        cout<<f[n][n];
        return 0;
    }

    规规整整的最长公共子序列动态规划(也苦苦啃了半天)

    提交 50分

    这才关注数据范围,10^5 ,n^2一定崩。

    于是发奋看题解,了解到离散的方式来处理。

    于是有了这样的变形,感觉比n^2高效了一些。能看懂这个离散,把公共子序列变为LIS 最长不下降子序列,是看了阮行止大佬的一篇题解

    大佬一语点破梦中人,为了让自己更清晰,我直接把第二个b数组弄成了一个相对于 a位置信息的数组,这样只要求b的lis问题就可以了。

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int a[100000],b[100000],map[100000],t,f[100000],ans;
    int main()
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            map[a[i]]=i;
        }
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&t);
            b[i]=map[t];
        }
        for(int i=1;i<=n;i++)
        {
            f[i]=1;
            for(int j=1;j<=i-1;j++)
            if(b[i]>b[j])
            {
                f[i]=max(f[i],f[j]+1);
            }
        }
        for(int i=1;i<=n;i++)
        {
            ans=max(f[i],ans);
        }
        cout<<ans;
    }

    结果还是50分。虽然提高了效率,但是还是n^2

    导弹拦截只得了一半分的锅又出来了,当时懒得去理解nlogn的算法,总要还。开始看这方面资料LIS nlogn算法

    大佬谆谆教诲的 传送门  

    有认识一个新的盲区,关于lowerbound和upperbound,再一次百度  另外一个大佬谆谆教诲的 传送门

    看懂了,AC。未来顺便补上导弹拦截的空缺。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int a[100000],b[100000],map[100000],t,f[100000],ans,temp[100000];
    int main()
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            map[a[i]]=i;
        }
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&t);
            b[i]=map[t];
        }
        int len=0;
        for(int i=1;i<=n;i++)
        {
            if(b[i]>temp[len])
            {
                temp[++len]=b[i];
                continue;
            }
            t=upper_bound(temp,temp+len+1,b[i])-temp;
            temp[t]=b[i];
        }
    cout<<len<<endl;
    }
  • 相关阅读:
    Elasticsearch 技术分析(五):如何通过SQL查询Elasticsearch
    IntelliJ IDEA 2018.3 重大升级,哪些功能打动了你?
    终于有人把“TCC分布式事务”实现原理讲明白了!
    Elasticsearch 技术分析(一): 基础入门
    拜托!面试请不要再问我Spring Cloud底层原理
    一个正则表达式引发的血案
    程序员啊,他又加班了
    程序员你为什么这么累 | 编码规范
    全文搜索引擎 ElasticSearch 还是 Solr?
    TCP三次握手原理,你真的了解吗?
  • 原文地址:https://www.cnblogs.com/stdcpsx/p/13093920.html
Copyright © 2011-2022 走看看