1. 程式人生 > >luogu P2215 [HAOI2007]上升序列

luogu P2215 [HAOI2007]上升序列

最小 esp family 字典 hide play 描述 cout bool

P2215 [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.


輸入輸出樣例

輸入樣例#1:
6
3 4 1 2 3 6
3
6
4
5
輸出樣例#1:
Impossible
1 2 3 6
Impossible

說明

數據範圍

N<=10000

M<=1000


n^2的lis能過。數據滿水的。反向找這個點最多以他為開頭能擴展幾個數.O(n*m+n*n)直接過

技術分享
#include<iostream>
#include
<cstdio> #include<cstdlib> #include<algorithm> using namespace std; const int INT=1e9+7; const int maxn=100000+999; int read(){ int an=0,f=1; char ch=getchar(); while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();} while(0<=ch&&ch<=9){an=an*10+ch-0;ch=getchar();}
return an*f; } int a[maxn],f[maxn],n,m; int main(){ n=read(); for(int i=1;i<=n;i++)a[i]=read(); f[n]=1; for(int i=n;i>0;i--){ for(int j=n;j>i;j--) if(a[i]<a[j]) f[i]=max(f[j]+1,f[i]); } m=read(); while(m){ m--; int k=read(),last=-INT; for(int i=1;i<=n;i++){ if( f[i]>=k&&k&&last<a[i] ){ cout<<a[i]<<" "; k--; last=a[i]; } } if(k)cout<<"Impossible"<<endl; else cout<<endl; } }
上升序列

by:s_a_b_e_r


水題qwq

開始以為挺難的,然而s一看這題,“這不就LIS嗎”

反著求一遍LIS,求出以i開頭的LIS長度

然後對於每個詢問,從頭掃一遍,如果有長度≥當前詢問的直接輸出就好了(貪心)

技術分享
#include<iostream>
#include<cstdio>
using namespace std;
const int N=10009,M=1009;
int a[N],n,m,f[N];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
    scanf("%d",&a[i]);
    for(int i=n;i>=1;--i)
    {
      f[i]=1;
      for(int j=n;j>=i;--j)
      if(a[i]<a[j])f[i]=max(f[i],f[j]+1);
    }
    scanf("%d",&m);
    while(m--)
    {
        int l,k=0;
        scanf("%d",&l);
        bool flag=1; 
        for(int i=1;i<=n&&l;++i)
        if(f[i]>=l&&a[i]>k)
        {
            flag=0;
            printf("%d ",a[i]);
            k=a[i];
            --l;
        }
        if(flag)printf("Impossible");
        cout<<endl;
    }
    return 0;
}
上升序列

by:wypx


luogu P2215 [HAOI2007]上升序列