[BZOJ1046] [HAOI2007]上升序列

传送门

http://www.lydsy.com/JudgeOnline/problem.php?id=1046

题目大意

对于1个数列,求出长度为a的位置字典序最小的LIS

题解

位置字典序最小,也就是说,只有遇到合法的就是字典序最小
怎么判断合法?
对于一个数它的后面LIS长度大于等于要的,并且比已加入的上一个数大即可
注意,LIS的长度达到a之后就停止

var
 x,y,z:array[0..20000]of longint;
 i,j,k:longint;
 n,m:longint;
 a,ans,l,r,mid,tt:longint;
function f(a:longint):longint;
begin
 l:=1; r:=ans;
 while l<r do
  begin
   mid:=(l+r)>>1;
   if y[mid]>a
   then l:=mid+1
   else r:=mid;
  end;
 exit(l);
end;

begin
 readln(n);
 for i:=1 to n do
  read(x[i]);
 y[1]:=x[n]; ans:=1; z[n]:=1;
 for i:=n-1 downto 1 do
  if x[i]<y[ans]
  then begin inc(ans); y[ans]:=x[i]; z[i]:=ans; end
  else begin tt:=f(x[i]); y[tt]:=x[i]; z[i]:=tt; end;
 readln(m);
 for i:=1 to m do
  begin
   readln(a);
   if a>ans
   then writeln('Impossible')
   else begin
    y[0]:=0; l:=0;
    for j:=1 to n do
     if a=0 then break else
     if (z[j]>=a)and(x[j]>l)
     then begin l:=x[j]; dec(a); inc(y[0]); y[y[0]]:=x[j]; end;
    for j:=1 to y[0]-1 do
     write(y[j],' ');
    writeln(y[y[0]]);
   end;
  end;
end.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值