hdu5489 Removed Interval
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 757 Accepted Submission(s): 282
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?
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.
the test case number starting from 1. Y is
the maximum length of LIS after removing the interval.
5 2
1 2 3 4 5
5 3
5 4 3 2 1
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的更多相关文章
- HDU5489 Removed Interval(动态规划)
一个长度为n的序列,删除任意长度为l的连续子序列后,求剩下的序列的最长公共子序列. 先求出以第i个元素为开始的LIS的长度,再一次循环,对所要求的结果更新 #include<iostream&g ...
- Hdu 5489 合肥网络赛 1009 Removed Interval
跳跃式LIS(nlogn),在普通的转移基础上增加一种可以跨越一段距离的转移,用一颗新的树状数组维护,同时,我们还要维护跨越完一次后面的转移,所以我用了3颗树状数组.. 比赛的时候一句话位置写错了,然 ...
- hdu 5489——Removed Interval——————【删除一段区间后的LIS】
Removed Interval Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- 2015合肥网络赛 HDU 5489 Removed Interval LIS+线段树(树状数组)
HDU 5489 Removed Interval 题意: 求序列中切掉连续的L长度后的最长上升序列 思路: 从前到后求一遍LIS,从后往前求一遍LDS,然后枚举切开的位置i,用线段树维护区间最大值, ...
- HDU 5489 Removed Interval (LIS变形)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5489 给你n个数,要删去其中连续的L个,问你删去之后的LIS最大是多少? 我们先预处理出以i下标为开头 ...
- HDU 5489 Removed Interval
题意:求一段序列中删掉L个连续元素后的LIS. 解法:我的想法很复杂= =怎么说呢……首先用nlogn的方法求LIS得到的序列dp的第i项的意义为上升子序列所有长度为i的序列结尾元素的最小值,那么先倒 ...
- 【二分】【最长上升子序列】HDU 5489 Removed Interval (2015 ACM/ICPC Asia Regional Hefei Online)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5489 题目大意: 一个N(N<=100000)个数的序列,要从中去掉相邻的L个数(去掉整个区间 ...
- HDU 5489 Removed Interval (LIS,变形)
题意: 给出一个n个元素的序列,要求从中删除任一段长度为L的连续子序列,问删除后的LIS是多少?(n<=10w, L<=n ,元素可能为负) 思路: 如果会O(nlogn)求普通LIS的算 ...
- 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 ...
随机推荐
- 四:WEB源码扩展
前言:WEB源码在安全测试中是非常重要的信息来源,可以用来进行代码审计漏洞也可以用来做信息突破口,其中WEB源码有很多技术需要简明分析,获取某ASP源码后就可以采用默认数据库下载为突破,获取某其他脚本 ...
- 【Problems】端口被占用 查看是被谁占用并关闭它
文章目录 Windows Linux 经常在Windows.Linux环境下运行JavaWeb项目,Tomcat的端口被占用了. 端口被占用就查看是被谁占用关闭它就行. Windows 在Window ...
- CTFHub - Web(五)
eval执行: 1.进入网页,显示源码, <?php if (isset($_REQUEST['cmd'])) { eval($_REQUEST["cmd"]); } els ...
- [工作札记]03: 微软Winform窗体中ListView、DataGridView等控件的Bug,会导致程序编译失败,影响范围:到最新的.net4.7.2都有
工作中,我们发现了微软.net WinForm的一个Bug,会导致窗体设计器自动生成的代码失效,这个Bug从.net4.5到最新的.net4.7.2都存在,一直没有解决.最初是我在教学工作中发现的,后 ...
- 小白也能看懂的ACID与隔离级别
前言 现如今JAVA开发工程师的数量越来越多,但大多数工程师平时做的工作都是简单的CRUD,当你一直处于这种舒适的环境中不追求进步的时候,如果哪一天你突然想要改变环境,换个工作,去与面试官当面聊技术的 ...
- 面对key数量多和区间查询低效问题:Hash索引趴窝,LSM树申请出场
摘要:Hash索引有两个明显的限制:(1)当key的数量很多时,维护Hash索引会给内存带来很大的压力:(2)区间查询很低效.如何对这两个限制进行优化呢?这就轮到本文介绍的主角,LSM树,出场了. 我 ...
- NoClassDefFoundError: javax/xml/bind/DatatypeConverter错误原因以及解决办法
nested exception is java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter 报错内容: org.sprin ...
- Linux 通过端口终止进程
以下命令可用于杀死占用某端口的所有进程. root 用户: kill -9 $(lsof -i tcp:进程号 -t) 非 root 用户: kill -9 $(sudo lsof -i tcp:进程 ...
- 一体化的Linux系统性能和使用活动监控工具–Sysstat
[转]原文出处: Tecmint-Kuldeep Sharma 译文出处:Linux Story-天寒 欢迎分享原创到伯乐头条 在监控系统资源.系统性能和使用活动方面,Sysstat的确是一个 ...
- Exception 异常处理
https://github.com/jazzband/django-redis/blob/master/django_redis/exceptions.py django-redis/base.py ...