zoukankan      html  css  js  c++  java
  • POJ 1887 Testingthe CATCHER (LIS:最长下降子序列)

    POJ 1887 Testingthe CATCHER (LIS:最长下降子序列)

    http://poj.org/problem?id=3903

    题意:

           给你一个长度为n (n<=200000) 的数字序列, 要你求该序列中的最长(严格)下降子序列的长度.

    分析:

           读取全部输入, 将原始数组逆向, 然后求最长严格上升子序列就可以.

           因为n的规模达到20W, 所以仅仅能用O(nlogn)的算法求.

           令g[i]==x表示当前遍历到的长度为i的全部最长上升子序列中的最小序列末尾值为x.(假设到眼下为止, 根本不存在长i的上升序列, 那么x==INF无穷大)

           如果当前遍历到了第j个值即a[j], 那么先找到g[n]数组的值a[j]的下确界(即第一个>=a[j]值的g[k]k). 那么此时表明存在长度为k-1的最长上升子序列且该序列末尾的位置<j且该序列末尾值<a[j].

           那么我们能够令g[k]=a[j] 且 dp[i]=k (dp含义如解法1).

           (上面一段花时间细致理解)

           终于我们能够找出下标最大的i使得: g[i]<INF 中i下标最大. 这个i就是LIS的长.

    AC代码: O(n*logn)复杂度

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=200000+5;
    const int INF=1e8;
    
    int n;
    int a[maxn];
    int g[maxn];
    
    int main()
    {
        int kase=0;
        while(scanf("%d",&a[1])==1 && a[1]!=-1)
        {
            if(kase>0) printf("
    ");
            n=2;
            while(scanf("%d",&a[n])==1 && a[n]!=-1)
            {
                n++;
            }
            n--;
    
            reverse(a+1,a+n+1);
            for(int i=1;i<=n;i++)
                g[i]=INF;
    
            int ans=0;
            for(int i=1;i<=n;i++)
            {
                int k=lower_bound(g+1,g+n+1,a[i])-g;
                g[k]=a[i];
                ans=max(ans,k);
            }
            printf("Test #%d:
      maximum possible interceptions: %d
    ",++kase,ans);
        }
        return 0;
    }
    

  • 相关阅读:
    springmvc log4j 配置
    intellij idea maven springmvc 环境搭建
    spring,property not found on type
    intellij idea maven 工程生成可执行的jar
    device eth0 does not seem to be present, delaying initialization
    macos ssh host配置及免密登陆
    centos7 搭建 docker 环境
    通过rest接口获取自增id (twitter snowflake算法)
    微信小程序开发体验
    gitbook 制作 beego 参考手册
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/6938465.html
Copyright © 2011-2022 走看看