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

HAOI2007 上升序列

时间:2015-03-27 22:06:21      阅读:164      评论:0      收藏:0      [点我收藏+]

标签:

题目大意:给定一个序列,求任意长度的上升子序列,要求字典序最小(这里的字典序是位置最小)

思路:用nlogn的做法求最长上升子序列,然后从头往后扫m遍,找后面的值大的同时f数组满足相应条件的值输出。求f数组的时候,用lower_bound wa了,但用upper_bound就ac了。。。

技术分享
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int a[10001]={0},d[10001]={0},f[10001]={0};
int main()
{
    freopen("lis.in","r",stdin);
    freopen("lis.out","w",stdout);
    
    int i,j,n,m,len=0,now,x;
    scanf("%d",&n);
    for (i=1;i<=n;++i) scanf("%d",&a[i]);
    memset(d,128,sizeof(d));
    d[n]=a[n];len=n;f[n]=1;
    for (i=n-1;i>=1;--i)
    {
        if (a[i]<d[len])
        {
            d[--len]=a[i];
            f[i]=n-len+1;
        }
        else
        {
            j=upper_bound(d+len+1,d+n+1,a[i])-d-1;
            if (d[j]!=a[i])
            {
                d[j]=a[i];f[i]=n-j+1;
            }
            else f[i]=n-j+1;
        }
    }
    scanf("%d",&m);len=n-len+1;
    for (i=1;i<=m;++i)
    {
        scanf("%d",&x);
        if (x>len) printf("Impossible");
        else
        {
            now=-2100000000;
            for (j=1;j<=n;++j)
            {
                if (f[j]>=x&&a[j]>now)
                {
                    printf("%d",a[j]);--x;now=a[j];
                    if (!x) break;
                    else printf(" ");
                }
            }
        }
        printf("\n");
    }
    
    fclose(stdin);
    fclose(stdout);
}
View Code

 

当得知n^2暴力能a的时候。。。

HAOI2007 上升序列

标签:

原文地址:http://www.cnblogs.com/Rivendell/p/4372920.html

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