• bzoj1046 [HAOI2007]上升序列


    题目链接

    二分优化LIS

    字典序最小的方案不好求。

    于是就倒过来求以一个数开头的最长上升子序列。

    字典序小的放前面。

    输出时取最优就好。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<string>
     5 #include<cstring>
     6 #include<cmath>
     7 #include<algorithm>
     8 #include<ctime>
     9 #include<queue>
    10 #include<map>
    11 #include<set>
    12 using namespace std;
    13 const int INF=2147483647;
    14 int n,f[10010],a[10010],stack[10010],top,temp,m,x;
    15 int main()
    16 {
    17     scanf("%d",&n);
    18     memset(stack,128,sizeof(stack));
    19     stack[top]=INF;
    20     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    21     for(int i=n;i>=1;i--)
    22     {
    23         int l=0,r=top,ans=0;
    24         while (l<=r)
    25         {
    26           int m=(l+r)>>1;
    27           if (a[i]<stack[m])ans=m,l=m+1;
    28           else r=m-1;
    29         }
    30         f[i]=ans+1;top=max(top,f[i]);
    31         stack[f[i]]=max(stack[f[i]],a[i]);    
    32     }
    33     scanf("%d",&m);
    34     for(int i=1;i<=m;i++)
    35     {
    36         scanf("%d",&x);
    37         if(x>top)cout<<"Impossible
    ";
    38         else if(!x)cout<<"
    ";
    39         else for(int i=1,t=-INF;i<=n;i++) 
    40               if(f[i]>=x&&t<a[i]) 
    41               {
    42                 printf("%d",a[i]),x--,t=a[i];
    43                 if(x)printf(" ");
    44                 else {cout<<"
    ";break;}
    45               }    
    46     }
    47     return 0;
    48 }
  • 相关阅读:
    [导入]Interesting Finds: 2007.12.17
    [导入]Interesting Finds: 2007.12.15
    [导入]Interesting Finds: 2007.12.13
    Interesting Finds: 2007.12.22
    吾生也有涯,而知也无涯。
    Hello world
    学习了clipboard复制剪切插件的使用
    在博客园学习成长
    命名空间概述
    Linux vi/vim
  • 原文地址:https://www.cnblogs.com/HugeGun/p/5151294.html
Copyright © 2020-2023  润新知