Special Subsequence


Time Limit: 5 Seconds      Memory Limit: 32768 KB

There a sequence S with n integers , and A is a special subsequence that satisfies |Ai-Ai-1| <= d ( 0 <i<=|A|))

Now your task is to find the longest special subsequence of a certain sequence S

Input

There are no more than 15 cases , process till the end-of-file

The first line of each case contains two integer n and d ( 1<=n<=100000 , 0<=d<=100000000) as in the description.

The second line contains exact n integers , which consist the sequnece S .Each integer is in the range [0,100000000] .There is blank between each integer.

There is a blank line between two cases

Output

For each case , print the maximum length of special subsequence you can get.

Sample Input

5 2
1 4 3 6 5 5 0
1 2 3 4 5

Sample Output

3
1

题解:让求|Ai-Ai-1| <= d 的最长子序列;
很简单就想到DP;
dp[i]表示前i个数的最长为多少,
则dp[i]=max(dp[j]+1) abs(a[i]-a[j])<=d
不出意外,肯定超时了;
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
using namespace std;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
typedef long long LL;
#define mem(x,y) memset(x,y,sizeof(x))
#define PI(x) printf("%d",x)
#define PL(x) printf("%lld",x)
#define SI(x) scanf("%d",&x)
#define SL(x) scanf("%lld",&x)
#define P_ printf(" ")
#define T_T while(T--)
const int MAXN=100010;
int dp[MAXN];
int m[MAXN];
int main(){
int n,d;
while(~scanf("%d%d",&n,&d)){
for(int i=0;i<n;i++)SI(m[i]);
mem(dp,0);
int ans=0;
for(int i=0;i<n;i++){
for(int j=0;j<i;j++){
if(abs(m[i]-m[j])<=d){
dp[i]=max(dp[i],dp[j]+1);
ans=max(ans,dp[i]);
}
}
}
printf("%d\n",ans+1);
}
return 0;
}

 

接下来就是如何高效地找到满足差值在d以内的最大值。

将数字进行离散化,对于一个新的数,就可以确定一个范围,然后在这个范围进行查找dp的最值+1即可。

线段树每一个结点保存的是这个区间的最值,叶子结点的值便是以这个数结尾的最长数量;

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
using namespace std;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
typedef long long LL;
#define mem(x,y) memset(x,y,sizeof(x))
#define PI(x) printf("%d",x)
#define PL(x) printf("%lld",x)
#define SI(x) scanf("%d",&x)
#define SL(x) scanf("%lld",&x)
#define P_ printf(" ")
#define T_T while(T--)
#define ll root<<1
#define rr root<<1|1
#define lson ll,l,mid
#define rson rr,mid+1,r
#define V tree[root]
const int MAXN=100010;
int tree[MAXN<<2];
int a[MAXN],b[MAXN];
int dp[MAXN];
int nm;
int pushup(int root){
tree[root]=max(tree[ll],tree[rr]);
}
void update(int root,int l,int r,int nt,int v){
int mid=(l+r)>>1;
if(l==r){
V=v;return;
}
if(mid>=nt)update(lson,nt,v);
else update(rson,nt,v);
pushup(root);
}
void query(int root,int l,int r,int L,int R){
if(l>=L&&r<=R){
nm=max(nm,V);
return;
}
int mid=(l+r)>>1;
if(mid>=L)query(lson,L,R);
if(mid<R)query(rson,L,R);
}
int main(){
int n,d;
while(~scanf("%d%d",&n,&d)){
for(int i=0;i<n;i++)SI(a[i]),b[i]=a[i];
sort(b,b+n);
mem(tree,0);mem(dp,0);
for(int i=0;i<n;i++){
int l,r;
l=lower_bound(b,b+n,a[i]-d)-b+1;
r=upper_bound(b,b+n,a[i]+d)-b+1-1;
nm=0;
query(1,1,n,l,r);
dp[i]=nm+1;
update(1,1,n,lower_bound(b,b+n,a[i])-b+1,dp[i]);
}
int ans=0;
for(int i=0;i<n;i++)ans=max(ans,dp[i]);
printf("%d\n",ans);
}
return 0;
}

  

Special Subsequence(离散化线段树+dp)的更多相关文章

  1. 干物妹小埋 (离散化 + 线段树 + DP)

    链接:https://ac.nowcoder.com/acm/contest/992/B来源:牛客网 题目描述 在之前很火的一个动漫<干物妹小埋>中,大家对小埋打游戏喝可乐的印象十分的深刻 ...

  2. 南阳理工 题目9:posters(离散化+线段树)

    posters 时间限制:1000 ms  |  内存限制:65535 KB 难度:6   描述 The citizens of Bytetown, AB, could not stand that ...

  3. SGU 180 Inversions(离散化 + 线段树求逆序对)

    题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=180 解题报告:一个裸的求逆序对的题,离散化+线段树,也可以用离散化+树状数组.因为 ...

  4. Tsinsen A1219. 采矿(陈许旻) (树链剖分,线段树 + DP)

    [题目链接] http://www.tsinsen.com/A1219 [题意] 给定一棵树,a[u][i]代表u结点分配i人的收益,可以随时改变a[u],查询(u,v)代表在u子树的所有节点,在u- ...

  5. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

  6. 【POJ】2528 Mayor's posters ——离散化+线段树

    Mayor's posters Time Limit: 1000MS    Memory Limit: 65536K   Description The citizens of Bytetown, A ...

  7. hpu校赛--雪人的高度(离散化线段树)

    1721: 感恩节KK专场——雪人的高度 时间限制: 1 Sec  内存限制: 128 MB 提交: 81  解决: 35 [提交][状态][讨论版] 题目描述 大雪过后,KK决定在春秋大道的某些区间 ...

  8. 【BZOJ1645】[Usaco2007 Open]City Horizon 城市地平线 离散化+线段树

    [BZOJ1645][Usaco2007 Open]City Horizon 城市地平线 Description Farmer John has taken his cows on a trip to ...

  9. 【bzoj4636】蒟蒻的数列 离散化+线段树

    原文地址:http://www.cnblogs.com/GXZlegend/p/6801379.html 题目描述 蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列 题目描述 DCrusher有一个 ...

随机推荐

  1. ViEmu for VS2013-3.2.1 破解(转)

    ViEmuVS2013-3.2.1 破解   VS升级到2013后,作为一个Vimer,自然需要更新最新的ViEmu插件,因为现在离了Vim,写代码已经寸步难行了. ViEmu 3.2.1的破解其实和 ...

  2. 使用泛型对java数组扩容

    编写一个通用方法,其功能是将数组扩展到10%+10个元素(转载请注明出处) package cn.reflection; import java.lang.reflect.Array; public ...

  3. 拦截API 注入进程

    本文详细的介绍了在Visual Studio(以下简称VS)下实现API钩子的编程方法,阅读本文需要基础:有操作系统的基本知识(进程管理,内存管理),会在VS下编写和调试Win32应用程序和动态链接库 ...

  4. hdu 1823 Luck and Love 二维线段树

    题目链接 很裸的题, 唯一需要注意的就是询问时给出的区间并不是l<r, 需要判断然后交换一下, WA了好多发... #include<bits/stdc++.h> using nam ...

  5. android studio2.0 搭建Robotium环境--有被测源代码的情况下

    1.导入robotium-solo-5.2.1.jar 包    导入junit:4.12.jar2.app- -src- -main- -libs 或者app-libs下 复制进去后,右键add a ...

  6. SQL Server | Mysql 对表的unique 的实现方式

    在ANSI SQL 标准中unique 有两种实现方式 1.是可以插入多个空值.也就是说多个null值看成是互不相同的. 2.是只可以插入一个空值,也主是说把所有的空值看也是相同的. 在SQL Ser ...

  7. Linux常用的系统监控shell脚本

    http://www.linuxqd.com下面是我常用的几个Linux系统监控的脚本,大家可以根据自己的情况在进行修改,希望能给大家一点帮助.1.查看主机网卡流量 #!/bin/bash #netw ...

  8. 自己动手写RTP服务器——传输所有格式的视频

    上一篇文章我们介绍了如何用一个简单的UDP socket搭建一个RTP服务器.我把这份80行的代码呈现到客户面前的时候,就有人不满意了. 还有人在参考的时候会问:“楼主你的TS格式的文件是哪里来的?应 ...

  9. rdo(remote data objects) repo openstack icehouse

    problem making ssl connection Error: Cannot retrieve repository metadata (repomd.xml) for repository ...

  10. SQL存储过程动态查询数据区间

    以前经常看到人查询数据库采用left join及case方式,一条一条的枚举查询整个数据的数据区间方法可行,但是数据一但很大,枚举就死悄悄,在网上查看,几乎全是照抄case ,left join枚举无 ...