码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 5773 最长上升子序列

时间:2016-07-30 17:59:00      阅读:126      评论:0      收藏:0      [点我收藏+]

标签:

题意 给出一个序列 问它的最长严格上升子序列多长 这个序列中的0可以被替代为任何数

n的范围给出了1e5 所以平常的O(n*n)lis不能用了 

在kuangbin的模板里有O(nlogn)的模板 套上就可以过了

但是比赛的时候没有拿模板= =. 于是就想出了另外一个时间复杂度不明的办法= =.

将序列从前往后扫

设定一个数组a a[i]=z  a[i]为当前i长度的上升子序列中的最小的尾数的大小 maxl为当前找出的最长的子序列长度

每次我们扫到一个数 都对0-maxl长度的a[i]进行判断 看能不能将他加到长度为i-1的序列的尾部 来优化a[i]使长度为i的序列的尾数更小

当遇到非0数的时候 只需要慢慢判断就好了 遇到0的时候 应当尽量的使0变换的数更小 则在优化的时候应当将0变为a[i-1]+1来与a[i]比较

最后的maxl即为答案

这个办法速度并不稳定 因为每次都要从0-maxl扫一遍 最差的时候是O(n*n)(当所给序列为上升序列时)

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<math.h>
#include<iostream>
using namespace std;
int n;
int a[100050]; /// every l - min wei
int maxl;
int main()
{
    int t;
    scanf("%d",&t);
    int tt=0;
    while(t--)
    {
        tt++;
        maxl=0;
        a[0]=-999999999;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            int x;
            scanf("%d",&x);
            if(x!=0)
            {
                if(x>a[maxl]){
                    maxl++;
                    a[maxl]=x;
                }
                for(int k=maxl;k>=2;k--)
                {
                    if(x>a[k-1]&&x<a[k])
                        a[k]=x;
                }
                if(x<a[1])
                    a[1]=x;
            }
            else
            {
                maxl++;
                a[maxl]=a[maxl-1]+1;
                for(int k=maxl-1;k>=1;k--)
                {
                    if(a[k]>a[k-1]+1)
                        a[k]=a[k-1]+1;
                }
            }
        }
        printf("Case #%d: ",tt);
        printf("%d\n",maxl);
    }
}

  

 

HDU 5773 最长上升子序列

标签:

原文地址:http://www.cnblogs.com/rayrayrainrain/p/5721286.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!