【BZOJ 1046】【HAOI 2007】上升序列

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的上升序列,则打印Impossible.

Input

  第一行一个N,表示序列一共有N个元素第二行N个数,为a1,a2,…,an 第三行一个M,表示询问次数。下面接M行每行一个数L,表示要询问长度为L的上升序列。N<=10000,M<=1000

Output

  对于每个询问,如果对应的序列存在,则输出,否则打印Impossible.

Sample Input

6
3 4 1 2 3 6
3
6
4
5

Sample Output

Impossible
1 2 3 6
Impossible

题解

这题很水,但我看错了题目——
注意是使子序列下标的字典序最小,而不是子序列的字典序最小,所以这题应该比较简单
先从后往前递最长下降子序列,也就是从前往后的最长上升子序列,得到以i开头的最长上升子序列长度f[i]。
然后对于每一次询问len,从1开始扫描,如果f[i]>=len就输出这个数,然后len减1,再往后查找。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

#define N 10010
int a[N],f[N],g[N];
int n,m,len;

int find(int x)
{
    int l = 1,r = len,ans;
    while(l <= r)
    {
        int mid = (l+r) >> 1;
        if(g[mid] > x)
        {
            l = mid + 1;
            ans = mid;
        } else r = mid - 1;
    }
    return ans;
}
void dp()
{
    for(int i = n;i >= 1;i--)
    {
        int t = find(a[i]);
        f[i] = t+1;
        len = max(len,t+1);
        if(g[t+1] < a[i]) g[t+1] = a[i];
    }
    return;
}

void work(int l)
{
    int last = 0;
    for(int i = 1;i <= n;i++)
        if(f[i] >= l && a[i] > last)
        {
            printf("%d",a[i]);
            if(l != 1)printf(" ");
            last = a[i];
            l--;
            if(!l) break;
        }
    printf("\n");
}           

int main()
{
    int l;
    scanf("%d",&n);
    for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
    dp();
    scanf("%d",&m);
    while(m--)
    {
        scanf("%d",&l);
        if(l > len) printf("Impossible\n");
            else work(l);
    }
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值