HAOI2007 上升序列

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

思路:用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);
}

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

时间: 2024-10-08 13:28:56

HAOI2007 上升序列的相关文章

BZOJ 1046: [HAOI2007]上升序列 LIS -dp

1046: [HAOI2007]上升序列 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3438  Solved: 1171[Submit][Status][Discuss] Description 对于一个给定的S={a1,a2,a3,…,an},若有P={ax1,ax2,ax3,…,axm},满足(x1 < x2 < … < xm)且( ax1 < ax2 < … < axm).那么就称P为S的一个上升序列.如果有多

【BZOJ】1046 : [HAOI2007]上升序列

1046: [HAOI2007]上升序列 题意:给定S={a1,a2,a3,…,an}问是否存在P={ax1,ax2,ax3,…,axm},满足(x1 < x2 < … < xm)且( ax1 < ax2 < … < axm),若存在多组符合长度为m的递增子序列,则输出以序号字典序最小的:并非是数值 Sample Input 6 3 4 1 2 3 6 3 6 4 5 Sample Output Impossible 1 2 3 6 Impossible 数据范围 N&

【BZOJ 1046】 1046: [HAOI2007]上升序列

1046: [HAOI2007]上升序列 Description 对于一个给定的S={a1,a2,a3,-,an},若有P={ax1,ax2,ax3,-,axm},满足(x1 < x2 < - < xm)且( ax1 < ax2 < - < axm).那么就称P为S的一个上升序列.如果有多个P满足条件,那么我们想求字典序最小的那个.任务给出S序列,给出若干询问.对于第i个询问,求出长度为Li的上升序列,如有多个,求出字典序最小的那个(即首先x1最小,如果不唯一,再看x2

1046: [HAOI2007]上升序列(dp)

1046: [HAOI2007]上升序列 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4999  Solved: 1738[Submit][Status][Discuss] Description 对于一个给定的S={a1,a2,a3,…,an},若有P={ax1,ax2,ax3,…,axm},满足(x1 < x2 < … < xm)且( ax1 < ax2 < … < axm).那么就称P为S的一个上升序列.如果有多

【BZOJ 1046】 [HAOI2007]上升序列

1046: [HAOI2007]上升序列 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 2688  Solved: 891 [Submit][Status] Description 对于一个给定的S={a1,a2,a3,-,an},若有P={ax1,ax2,ax3,-,axm},满足(x1 < x2 < - < xm)且( ax1 < ax2 < - < axm).那么就称P为S的一个上升序列.如果有多个P满足条件,那

BZOJ 1046: [HAOI2007]上升序列(LIS)

题目挺坑的..但是不难.先反向做一次最长下降子序列.然后得到了d(i),以i为起点的最长上升子序列,接下来贪心,得到字典序最小. ------------------------------------------------------------------- #include<cstdio> #define rep(i,n) for(int i=0;i<n;++i) using namespace std; const int maxn=10005; const int inf=0

bzoj 1046 : [HAOI2007]上升序列 dp

题目链接 1046: [HAOI2007]上升序列 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3620  Solved: 1236[Submit][Status][Discuss] Description 对于一个给定的S={a1,a2,a3,…,an},若有P={ax1,ax2,ax3,…,axm},满足(x1 < x2 < … < xm)且( ax1 < ax2 < … < axm).那么就称P为S的一个上升序列

[bzoj1046][HAOI2007]上升序列

题意:对于一个给定的S={a1,a2,a3,-,an},若有P={ax1,ax2,ax3,-,axm},满足(x1 < x2 < - < xm)且( ax1 < ax2 < - < axm).那么就称P为S的一个上升序列. 有m个询问,每次询问一个长度L,如果没有长度为L的上升序列,输出Impossible,要不然求一个字典序最小的上升序列. (这题的字典序最小居然指的是下标) n<=10000,m<=1000 题解:倒着dp,用线段树求出每个点和它后面最长

【bzoj1046】[HAOI2007]上升序列

首先求出以每个数为开头上升序列长度,即倒着做最长下降子序列 然后,把字典序尽量小的放前面 即若要求的序列长度为x,如果以第一个数(字典序最小的数)开头的最长上升子序列大等于x,则将它放在答案第一个,第二个数开头小于x,则舍弃,第三个大于x-1,放答案第二个,以此类推 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio>

[BZOJ1046] [HAOI2007] 上升序列 (dp)

Description 对于一个给定的S={a1,a2,a3,…,an},若有P={ax1,ax2,ax3,…,axm},满足(x1 < x2 < … < xm)且( ax1 < ax2 < … < axm).那么就称P为S的一个上升序列.如果有多个P满足条件,那么我们想求字典序最小的那个.任务给出S序列,给出若干询问.对于第i个询问,求出长度为Li的上升序列,如有多个,求出字典序最小的那个(即首先x1最小,如果不唯一,再看x2最小……),如果不存在长度为Li的上升序列