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 ...
随机推荐
- Docker学习笔记之使用Docker数据卷
Docker数据卷将数据存储到主机而非容器,多个容器需要共享数据时,常常使用数据卷. 1. 为容器设置数据卷(不指定主机目录) 2. 容器与主机之间.容器与容器之间共享数据卷(指定主机目录) 3. 使 ...
- 九:APP及其他资产
APP提取一键反编译提取 APP抓数据包进行工具配合 各种第三方应用相关探针技术 各种服务器接口相关探针技术 APP提取及抓包及后续配合 某APK一键提取反编译 利用burp历史抓更多URL 某IP无 ...
- spring cloud gateway 日志打印
从api请求中获取访问的具体信息,是一个很常见的功能,这几天在研究springcloud,使用到了其中的gateway,刚好将研究的过程结果都记录下来 0. Version <parent> ...
- leetcode刷题录-1395
目录 题目 思考过程 查看别人分享的思路 总结 题目 题目地址:https://leetcode-cn.com/problems/count-number-of-teams/ n 名士兵站成一排.每个 ...
- Poj-P1088题解【动态规划/记忆化搜索】
本文为原创,转载请注明:http://www.cnblogs.com/kylewilson/ 题目出处: http://poj.org/problem?id=1088 题目描述: 区域由一个二维数组给 ...
- [Usaco2008 Mar]River Crossing渡河问题
题目描述 Farmer John以及他的N(1 <= N <= 2,500)头奶牛打算过一条河,但他们所有的渡河工具,仅仅是一个木筏. 由于奶牛不会划船,在整个渡河过程中,FJ必须始终在木 ...
- libuv中实现tcp服务器
目录 1.说明 2.libuv的tcp server 3.API简介 3.1.uv_tcp_init 3.2.uv_ip4_addr 3.3.uv_tcp_bind 3.4.uv_listen 3.5 ...
- Python+Selenium+Unittest实现PO模式web自动化框架(8)
1.main.py模块的功能 最后就是要有一个项目入口,并且是需要加载测试用例集. # --^_^-- coding:utf-8 --^_^-- # @Remark:运行入口 "" ...
- git commit前检测husky与pre-commit 提交钩子
git commit前检测husky与pre-commit git commit前检测husky与pre-commit - 简书 https://www.jianshu.com/p/f0d31f92b ...
- 并发安全 sync.Map
https://mp.weixin.qq.com/s/MqPm7QH3_D9roVkpTs9Xpw 谈谈Go的并发安全相关 原创 歪鼻子 歪鼻子 2020-12-27 package main ...