HDU

来源:互联网 发布:wampserver无法打开php 编辑:程序博客网 时间:2024/06/05 15:14

HDU - 5489入口

题意:给定n(n<=100000)个数a1---an,求去掉连续m(m<n)个数后的最长上升子序列?

分析:假设去掉第k(k>m)项左边的m个数(不包含k)所得到的LIS最长。并且a[k]在最长上升子序列中。倘若去掉当前区间的数的情况下,a[k]在LIS子序列中的答案不是最佳,则a[k]不在最长LIS中,即a[k]可以去掉(去掉的区间右移),去掉k项左边的m个数的最长LIS并没有遗漏。然后就是求出以k为第一项的右区间最长LIS。加上左边小于a[k]的最长LIS。

ACcode

#include<cstdio>#include<iostream>#include<cstring>using namespace std;const int N=101000;int a[N],b[N],n,m,x,tr[N],ans,len,d[N];int main(){    int TA,cas=1;    scanf("%d",&TA);    while(TA--)    {        ans=len=0;        scanf("%d%d",&n,&m);        for(int i=1;i<=n;i++)        {scanf("%d",&a[i]);         b[i]=-a[i];        }        memset(d,0x3f,sizeof(d));        for(int i=n;i>0;i--)        {            x=lower_bound(d+1,d+n+1,b[i])-d;            d[x]=b[i];            tr[i]=x;        }        memset(d,0x3f,sizeof(d));        for(int i=m+1;i<=n;i++)        {            x=lower_bound(d+1,d+n+1,a[i])-d;            ans=max(ans,x-1+tr[i]);            x=lower_bound(d+1,d+n+1,a[i-m])-d;            d[x]=a[i-m];            len=max(len,x);        }        ans=max(len,ans);        printf("Case #%d: %d\n",cas++,ans);    }    return 0;}


原创粉丝点击