hdu 5389(LIS 搞一搞)

来源:互联网 发布:php session同步 编辑:程序博客网 时间:2024/06/08 00:01

题意:对一个数列删除连续长度为L的数剩下的数列的最长递增子序列最大。


思路:先预处理一下以i开始到结尾的数列的以a[i]为LIS 为最后一个数的数的长度,不是LIS !

然后对于这样的话每次枚举i,每次查询操作之后把i - m这个元素加入的数组中。


#include<bits/stdc++.h>using namespace std;#define INF 0x3f3f3f3f#define clr(x,y) memset(x,y,sizeof x)typedef long long ll;const int maxn = 2e5 + 10;int a[maxn],b[maxn],c[maxn],d[maxn];int st[maxn];int len1[maxn],len2[maxn];int main(){    int n,m;    int Tcase;scanf("%d",&Tcase);    for(int ii = 1;ii <= Tcase;ii ++)    {        scanf("%d%d",&n,&m);        for(int i = 1;i <= n;i ++)scanf("%d",&a[i]),b[i] = -a[i];        clr(st,INF);        int cnt = 0;st[++ cnt] = b[n];len2[n] = 1;        for(int i = n - 1;i >= 1; i --)        {            int pos = lower_bound(st + 1,st +cnt + 1,b[i]) - st;            if(pos > cnt)cnt ++;            st[pos] = b[i];len2[i] = pos;        }        int ans = 0;        cnt = 0;clr(st,INF);        for(int i = m + 1; i <= n;i ++)        {            int pos = lower_bound(st + 1,st + cnt + 1,a[i]) - st;            ans = max(ans,pos - 1 + len2[i]);            pos = lower_bound(st + 1,st + cnt + 1,a[i - m]) - st;            if(pos > cnt)cnt ++;            st[pos] = a[i - m];            if(i == n)            {                ans = max(ans,cnt);            }        }        printf("Case #%d: %d\n",ii,ans);    }    return 0;}


原创粉丝点击