• [HAOI2007] 上升序列


    【问题描述】

     对于一个给定的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.

    【输入格式】 
      第一行一个N,表示序列一共有N个元素

    第二行N个数,为a1,a2,…,an

    第三行一个M,表示询问次数。下面接M行每行一个数L,表示要询问长度为L的上升序列。

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

    【输入样例】 
    6
    3 4 1 2 3 6
    3
    6
    4
    5


    【输出样例】 
    Impossible
    1 2 3 6
    Impossible

    【数据范围】

    N<=10000 M<=1000

    最长下降,贪心。蛮难的。一开始理解错了题目意思。

     1 #include<iostream>
     2 #include<fstream>
     3 //#define fout cout
     4 using namespace std;
     5 ifstream fin("lis.in");
     6 ofstream fout("lis.out");
     7 
     8 int n,m,a[10005]={0},b[10005],c[10005],len=0;
     9 
    10 int Erfen(int x){
    11     int l=1,r=len,mid;
    12     while(l<=r)
    13     {
    14       mid=(l+r)>>1;
    15       if(c[mid]==x) return mid;
    16       else if(c[mid]<x) r=mid-1;
    17       else l=mid+1;
    18               }
    19     return l;
    20     }
    21 
    22 int main()
    23 {
    24     fin>>n;
    25     
    26     for(int i=1;i<=n;++i) fin>>a[i];
    27     
    28     for(int i=n;i>=1;--i)
    29     {
    30       int l=Erfen(a[i]);
    31       if(l>len) len++;
    32       c[l]=a[i];
    33       b[i]=l;
    34             }
    35 
    36     fin>>m;
    37     for(int i=1;i<=m;++i)
    38     {
    39       int x,j;
    40       fin>>x;
    41       for(j=1;j<=n;++j)
    42       if(b[j]>=x) break;
    43       if(j>n) {fout<<"Impossible"<<endl;continue;}
    44       int tot=1,last=0;
    45       for(j;j<=n;++j)
    46       if(a[j]>a[last]&&b[j]>x-tot) {if(tot<x) fout<<a[j]<<" ";else {fout<<a[j]<<endl;break;}last=j;tot++;}
    47             }
    48    // system("pause");
    49     return 0;
    50     
    51     }
  • 相关阅读:
    CCF-Python的内置函数们
    CCF2019-03-Python题解
    Find a Number (记忆化+BFS)
    LeetCode15:三数之和(双指针)
    LeetCode:不用加号的加法(位运算)
    剑指Offer43:1~n整数中1出现的次数(数位DP)
    LeetCode190:颠倒二进制(位运算分治! 时间复杂度O(1))
    LeetCode5716:好因子的最大数目(数学、快速幂)
    python学习笔记:python的字符串拼接效率分析
    LeetCode1806:还原排列的最少操作步数(置换群 or 模拟)
  • 原文地址:https://www.cnblogs.com/noip/p/2745692.html
Copyright © 2020-2023  润新知