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 ...
随机推荐
- 【栈和队列】5、队列概述与数组队列的基本实现 - Java
3-5 数组队列 简单记录 - bobo老师的玩转算法系列–玩转数据结构 - 栈和队列 队列Queue 队列也是一种线性结构 相比数组,队列对应的操作是数组的子集 只能从一端(队尾)添加元素,只能从另 ...
- kubernets之pod的标签
一 如何查看pod 的日志 1 通过执行命令查看日志信息 kubectl logs pod_name 二 创建带有标签的pod,一个范例的pod创建yaml文件如下所示 2.1 创建带有 ...
- ctfhub技能树—sql注入—布尔盲注
打开靶机 查看页面信息 开始试验,查看返回信息 此题存在一个问题,如果没有数据,也是返回query_success 如此一来,就无法使用and组合进行注入,在看了其他大佬的解题过程后,知道了可以使用& ...
- C#使用OracleParameter操作数据库
public static int GetScalar(string sql,params OracleParameter [] OracleParms) { using (OracleConnect ...
- SAP client锁定
今天发现一个函数可以锁定SAP CLIENT . SCCR_LOCK_CLIENT 参数是client号码. 还可以通过事物SU10批量锁定用户登陆client
- SAP里会话结束方法(杀死进程)
在SAP的ERP里,有很多方法可以结束一个会话,然而在不同情况下,需要使用的方法也不同.下面从先后顺序来简单说明:1.SM04:最常用的方法,在SM04点击工具栏的会话->结束会话,来关闭一个会 ...
- CS_WHERE_USED_MAT 反查BOM的成品CS15
可能很多人都用过BOM展开的函数,但是有的时候,需要通过组件去反查BOM的成品,而这时候就需要用到函数 CS_WHERE_USED_MAT来实现,而对于CS_WHERE_USED_MAT只能反查到上一 ...
- 1V升压5V和1.5V升压5V的集成电路芯片
1.5V和1V输入,要升压输出5V的集成电路芯片合适? 干电池标准电压是1.5V,放电电压后面在0.9V-1V左右,如果要选用干电池1.5V升压到5V的合适的芯片,需要满足低压1V或者0.9V更好的低 ...
- Spring Security 实战干货:AuthenticationManager的初始化细节
1. 前言 今天有个同学告诉我,在Security Learning项目的day11分支中出现了一个问题,验证码登录和其它登录不兼容了,出现了No Provider异常.还有这事?我赶紧跑了一遍还真是 ...
- JS获取本机地址,生成地图
dome代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...