Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 757    Accepted Submission(s): 282


Problem Description
Given a sequence of numbers A=a1,a2,…,aN,
a subsequence b1,b2,…,bk of A is
referred as increasing if b1<b2<…<bk.
LY has just learned how to find the longest increasing subsequence (LIS).

Now that he has to select L consecutive
numbers and remove them from A for
some mysterious reasons. He can choose arbitrary starting position of the selected interval so that the length of the LIS of the remaining numbers is maximized. Can you help him with this problem?
 

Input
The first line of input contains a number T indicating
the number of test cases (T≤100).

For each test case, the first line consists of two numbers N and L as
described above (1≤N≤100000,0≤L≤N).
The second line consists of N integers
indicating the sequence. The absolute value of the numbers is no greater than 109.

The sum of N over all test cases will not exceed 500000.
 

Output
For each test case, output a single line consisting of “Case #X: Y”. X is
the test case number starting from 1. Y is
the maximum length of LIS after removing the interval.
 

Sample Input

2
5 2
1 2 3 4 5
5 3
5 4 3 2 1
 

Sample Output

Case #1: 3

Case #2: 1

这题想了很长时间,题意是求切去长度为l的连续子序列后,剩下的序列的最长上升子序列,切的起始位置随意定。

可以记录两个函数

f[i]:以a[i]为尾端的lis的最大长度。

g[i]:以a[i]为起始点的lis的最大长度。两者都包含a[i]。

这样对于每一个点,我们可以根据i, 找到 [0,i−L−1]之间的一个值,使得这个值小于a[i],且长度最大,可以用线段树来维护。然后用maxx=max(maxx,ans+g[i]),即前半段加上后半段就行了。

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
#define maxn 100060
int f[maxn],g[maxn],pos[maxn],a[maxn],c[maxn],a1[maxn],h[maxn];
struct node{
int l,r,maxnum;
}b[4*maxn]; void build(int l,int r,int i)
{
int mid;
b[i].l=l;b[i].r=r;b[i].maxnum=0;
if(l==r)return;
mid=(l+r)/2;
build(l,mid,i*2);
build(mid+1,r,i*2+1);
} void update(int idx,int num,int i)
{
int mid;
if(b[i].l==idx && b[i].r==idx){
b[i].maxnum=max(b[i].maxnum,num);return;
}
mid=(b[i].l+b[i].r)/2;
if(idx<=mid)update(idx,num,i*2);
else update(idx,num,i*2+1);
b[i].maxnum=max(b[i*2].maxnum,b[i*2+1].maxnum);
} int question(int l,int r,int i)
{
int mid;
if(l>r)return 0;
if(b[i].l==l && b[i].r==r){
return b[i].maxnum;
}
mid=(b[i].l+b[i].r)/2;
if(r<=mid) return question(l,r,i*2);
else if(l>mid)return question(l,r,i*2+1);
else{
int lv=question(l,mid,i*2);
int rv=question(mid+1,r,i*2+1);
return max(lv,rv);
} } int main()
{
int n,m,i,j,T,l,tot,len,maxx,ans,num1=0,k;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&l);
tot=0;
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
pos[i]=a[i];
}
sort(pos+1,pos+1+n);
tot=unique(pos+1,pos+1+n)-pos-1;
for(i=1;i<=n;i++)a[i]=lower_bound(pos+1,pos+1+tot,a[i])-pos;
f[1]=1;len=1;c[1]=a[1];
for(i=2;i<=n;i++){
if(a[i]>c[len]){
len++;f[i]=len;
c[len]=a[i];continue;
}
j=lower_bound(c+1,c+1+len,a[i])-c;
c[j]=a[i];
f[i]=j; //这里很重要,是j,不是len,因为求的是以a[i]为结尾的最长长度,不是前i个的最长长度
} for(i=1;i<=n;i++){
a1[i]=-a[n+1-i];
} g[1]=1;len=1;c[1]=a1[1];
for(i=2;i<=n;i++){
if(a1[i]>c[len]){
len++;g[i]=len;
c[len]=a1[i];continue;
}
j=lower_bound(c+1,c+1+len,a1[i])-c;
c[j]=a1[i];
g[i]=j;
}
reverse(g+1,g+1+n); build(1,100000,1);
maxx=0;
for(i=l+1;i<=n;i++){
ans=question(1,a[i]-1,1);
update(a[i-l],f[i-l],1);
maxx=max(maxx,ans+g[i]);
}
if(n-l>=1){
maxx=max(maxx,f[n-l]);
}
num1++;
printf("Case #%d: %d\n",num1,maxx);
}
return 0;
}
/*
2
10 2
1 2 3 9 8 7 4 5 6 7
*/

hdu5489 Removed Interval的更多相关文章

  1. HDU5489 Removed Interval(动态规划)

    一个长度为n的序列,删除任意长度为l的连续子序列后,求剩下的序列的最长公共子序列. 先求出以第i个元素为开始的LIS的长度,再一次循环,对所要求的结果更新 #include<iostream&g ...

  2. Hdu 5489 合肥网络赛 1009 Removed Interval

    跳跃式LIS(nlogn),在普通的转移基础上增加一种可以跨越一段距离的转移,用一颗新的树状数组维护,同时,我们还要维护跨越完一次后面的转移,所以我用了3颗树状数组.. 比赛的时候一句话位置写错了,然 ...

  3. hdu 5489——Removed Interval——————【删除一段区间后的LIS】

    Removed Interval Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  4. 2015合肥网络赛 HDU 5489 Removed Interval LIS+线段树(树状数组)

    HDU 5489 Removed Interval 题意: 求序列中切掉连续的L长度后的最长上升序列 思路: 从前到后求一遍LIS,从后往前求一遍LDS,然后枚举切开的位置i,用线段树维护区间最大值, ...

  5. HDU 5489 Removed Interval (LIS变形)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5489 给你n个数,要删去其中连续的L个,问你删去之后的LIS最大是多少? 我们先预处理出以i下标为开头 ...

  6. HDU 5489 Removed Interval

    题意:求一段序列中删掉L个连续元素后的LIS. 解法:我的想法很复杂= =怎么说呢……首先用nlogn的方法求LIS得到的序列dp的第i项的意义为上升子序列所有长度为i的序列结尾元素的最小值,那么先倒 ...

  7. 【二分】【最长上升子序列】HDU 5489 Removed Interval (2015 ACM/ICPC Asia Regional Hefei Online)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5489 题目大意: 一个N(N<=100000)个数的序列,要从中去掉相邻的L个数(去掉整个区间 ...

  8. HDU 5489 Removed Interval (LIS,变形)

    题意: 给出一个n个元素的序列,要求从中删除任一段长度为L的连续子序列,问删除后的LIS是多少?(n<=10w, L<=n ,元素可能为负) 思路: 如果会O(nlogn)求普通LIS的算 ...

  9. HDU 5489 Removed Interval 2015 ACM/ICPC Asia Regional Hefei Online (LIS变形)

    定义f[i]表示以i为开头往后的最长上升子序列,d[i]表示以i为结尾的最长上升子序列. 先nlogn算出f[i], 从i-L开始枚举f[i],表示假设i在最终的LIS中,往[0,i-L)里找到满足a ...

随机推荐

  1. JVM-Class文件的结构

    Class类文件的结构 Class文件是一株以8个字节为单位的二进制流.各个数据项目严格按照顺序紧凑的排列在文件之中,中间没有任何的分隔符,当遇到占用的空间大于8个字节时,会按照高位在前的方式进行分割 ...

  2. Python 中的面向接口编程

    前言 "面向接口编程"写 Java 的朋友耳朵已经可以听出干茧了吧,当然这个思想在 Java 中非常重要,甚至几乎所有的编程语言都需要,毕竟程序具有良好的扩展性.维护性谁都不能拒绝 ...

  3. 根据业务摸索出的一个selenium代码模版(python)

    前言 总算入行上班几个月了,不得不说业务是真的不消停啊.. 本人工作上经常遇到一种场景:为甲方做自动化接口处理工具,登录需要短信验证码,, 嘛算是摸索出了一套selenium代码模板,主要解决如下痛点 ...

  4. http-请求和响应报文的构成

    请求的构成: 1)请求方法URI协议/版本 2)请求头(Request Header) 3)请求正文 1)请求方法URI协议/版本 Request URL: http://localhost:8080 ...

  5. 【Java】计算机软件、博客的重要性、编程语言介绍和发展史

    之前学得不踏实,重新复习一遍,打扎实基础中. 记录 Java核心技术-宋红康_2019版 & Java零基础学习-秦疆 文章目录 软件开发介绍 软件开发 什么是计算机? 硬件及冯诺依曼结构 计 ...

  6. 转 Jmeter测试实践:文件上传接口

    Jmeter测试实践:文件上传接口   1.打开jmeter4.0,新建测试计划,添加线程组.根据实际情况配置线程属性. 2.添加HTTP请求. Basic部分修改如下: Advanced部分我做任何 ...

  7. shell批量解压源码包

    有时候部署环境有很多安装包,如果一个一个地解压缩实在太麻烦了,可以用shell批量进行解压缩.命令如下: [root@localhost ~]# vi tar.sh #! /bin/bash #标称是 ...

  8. .net core 不同地区时间相互转换

    .net core 不同地区时间相互转换 //韩国时间转换成当前时间 //value=需要转换的时间 //Korea Standard Tim 韩国时间 //China Standard Time 中 ...

  9. WPF入门学习(转)

    WPF基础知识 总结的学习WPF的几点基础知识: 1) C#基础语法知识(或者其他.NET支持的语言):这个是当然的了,虽然WPF是XAML配置的,但是总还是要写代码的,相信各位读者应该也都有这个基础 ...

  10. memset 在c++中使用细节注意

    C语言,在利用struct进行数据封装时,经常会使用memset(this,0,sizeof(*this))来初始化.而C++中,有时候也会用到struct,在利用memset进行初始化时,非常容易踩 ...