码迷,mamicode.com
首页 > 编程语言 > 详细

[BZOJ 1046][HAOI 2007]上升序列(nlogn的LIS算法)

时间:2014-12-03 19:25:46      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   io   ar   os   sp   for   on   

题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1046

有人说这题是NOIP难度?表示怀疑,蒟蒻认为此题难度略大于NOIP。。。。

这个题的序列长度n<=1e4,如果用n^2的LIS做法肯定TLE,只能用nlogn的算法,这种算法在http://www.slyar.com/blog/longest-ordered-subsequence.html中有详细讲解。

由于题目题意要求,我们需要求出以每个数字开头的最长上升子序列长度,但是LIS最终得出的是每个数字结尾的最长子序列长度,所以我们需要把这个序列倒过来做,倒过来DP,求出在倒着的序列中,以每个数字结尾的最长下降子序列长度,这就相当于原序列中以每个数字开头的最长上升子序列长度了。

然后再输出答案即可。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>

#define MAXN 100010

using namespace std;

int n,m,cnt,a[MAXN],f[MAXN],best[MAXN]; //f[i]=以第i个数字结尾的最长下降子序列长度,best[i]=长度为i的LIS的第i个元素,cnt=LIS长度

int BinarySearch(int x) //二分寻找大于x且最接近x的元素
{
    int lowerBound=1,upperBound=cnt,ans=0;
    while(lowerBound<=upperBound)
    {
        int mid=(lowerBound+upperBound)/2;
        if(best[mid]>x)
        {
            ans=mid;
            lowerBound=mid+1;
        }
        else upperBound=mid-1;
    }
    return ans;
}

void solve(int x) //输出长度为x的上升子序列
{
    int last=0; //已经输出的上升序列的最后一个数字
    for(int i=1;i<=n;i++)
        if(f[i]>=x&&a[i]>last)
        {
            printf("%d",a[i]);
            if(x!=1) printf(" "); //不是输出最后一个数字,就要输出空格,BZOJ好像不会过滤掉行末空格,所以要这样做,防WA
            last=a[i];
            x--;
            if(!x) break;
        }
    printf("\n");
}

void preDP() //DP预处理
{
    for(int i=n;i>=1;i--)
    {
        int t=BinarySearch(a[i]);
        f[i]=t+1;
        cnt=max(cnt,t+1);
        if(best[t+1]<a[i])
            best[t+1]=a[i];
    }
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    preDP();
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        int len;
        scanf("%d",&len);
        if(len<=cnt)
            solve(len);
        else puts("Impossible");
    }
    return 0;
}




[BZOJ 1046][HAOI 2007]上升序列(nlogn的LIS算法)

标签:style   blog   http   io   ar   os   sp   for   on   

原文地址:http://blog.csdn.net/qpswwww/article/details/41699651

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