HDU5773 The All-purpose Zero

来源:互联网 发布:蒲公英淘客软件 编辑:程序博客网 时间:2024/06/05 09:14

HDU5773 The All-purpose Zero

  • HDU5773 The All-purpose Zero
    • 题意
    • 题解
    • 代码

题意

  • HDU5773多校训练2016第四场1010题
  • 求一串数的LIS,0可以变为任意数

题解

多校第四轮,引用自官方解答

0可以转化成任意整数,包括负数,显然求LIS时尽量把0都放进去必定是正确的。因此我们可以把0拿出来,对剩下的做O(nlogn)的LIS,统计结果的时候再算上0的数量。为了保证严格递增,我们可以将每个权值S[i]减去i前面0的个数,再做LIS,就能保证结果是严格递增的。

刚好复习LIS的O(nlogn)求法,本质上就是,维护当前最长序列,当新数比末尾数更大,加入序列末尾,序列增长,如果小于,那么更新序列中可插入位置的数,保证后续能取得更优解。
例如:
12**4**5
->12**3**5

代码

#include <cstdio> #define MAX 100000#define INF 1000000int a[MAX], c[MAX], len;int find(int L,int R,int x){    if(L==R) return L;    int mid=(L+R)>>1;    if(c[mid]<x) return find(mid+1,len,x);    else return find(L,mid,x);}int main(){    int i,cas,n,t,m,T,b,k,ans,j,max,zero;    scanf("%d",&T);    for(cas=1;cas<=T;++cas)    {        scanf("%d",&n);        zero=0;        for(i=0,m=0;i<n;i++)        {            scanf("%d",&a[i]);            if(a[i] == 0)                ++zero;            else                a[m++] = a[i] - zero;        }        len=0;  c[0]=-INF;        for(i=0;i<m;i++)        {            if(a[i]>c[len]) j=++len;            else j=find(1,len,a[i]);            c[j]=a[i];        }        printf("Case #%d: %d\n", cas,len+zero);    }}
0 0