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 ...
随机推荐
- Python_列表(list)
list()类中的提供的操作 1.索引取值 li = [11,22,33,44,55] v1 = li[3] print(li[2]) #索引取出33 print(v1) #索引取出44 print( ...
- 利用Python-docx 读写 Word 文档中的正文、表格、段落、字体等
前言: 前两篇博客介绍了 Python 的 docx 模块对 Word 文档的写操作,这篇博客将介绍如何用 docx 模块读取已有 Word 文档中的信息. 本篇博客主要内容有: 1.获取文档的章节信 ...
- 【RAC】双节点RAC搭建
本文主要是双节点的RAC进行搭建,根据黄伟老师的视频进行总结和使用. 搭建环境: 1.两台安装好Linux_x64系统的服务器 2.IP设置 注意:Priv-IP的IP是自己一个网段,而剩下的SCAN ...
- 【Oracle】修改列的大小
alter table 表名 modify column_name varchar2(32) alter table 表名 modify (column_name1 varchar(20) defa ...
- 【Linux】ssh互信脚本
使用互信脚本的时候,需要敲回车,但是shell脚本无法满足,所以需要用到expect脚本 rpm -qa | grep expect 如果没有的话,直接用yum安装即可 yum install exp ...
- apijson简单使用
apijson简单使用 介绍 APIJSON 是一种专为 API 而生的 JSON 网络传输协议 以及 基于这套协议实现的 ORM 库.为简单的增删改查.复杂的查询.简单的事务操作 提供了完全自动化的 ...
- Oracle 常用命令大全(持续更新)
数据库 ----数据库启动 & 关闭 启动数据库 SQL> startup nomount; SQL> alter database mount; SQL> alter da ...
- 盼望着,盼望着。它终于来了!!!剪辑Windows PC测试版!
盼望着,盼望着.它终于来了!!!剪辑Windows PC测试版! 喜欢短视频抖音的小伙伴们,是不是都对手机抖音剪映操作不是很满意.期待WINDOWS电脑版剪映的来临.在此之前只有MAC版本,不能满足广 ...
- 前端面试准备笔记之JavaScript(03)
01. 变量声明提升 在预解析的时候,成员变量和函数,被提升到最高的位置,方便其他程序访问. 可以先使用后声明. 只提升变量名,不提升变量值 let const 声明的变量不具有变量声明提升. // ...
- 网络基础知识之Cisco
2021-01-2313:35:21 大家好,我是新手,刚学完Cisco协议,以后,我会每天都会给大家一些学习笔记 和一些学习心得,这方面不会的可以找我.qq2934896930. 网络的定义: 计算 ...