Special Subsequence
Time Limit: 5000MS | | Memory Limit: 32768KB | | 64bit IO Format: %lld & %llu |
Submit Status
Description
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
//知道它是个DP,但没想到是这么屌的一个DP,看着大神的博客,愣是看了两个小时才稍微有点理解(加上找错。。。)。唉,DP这条路好难走。。。
//再贴代码之前先介绍一下unique()函数:
unique()函数是一个去重函数,STL中unique的函数 unique的功能是去除相邻的重复元素(只保留一个), 还有一个容易忽视的特性是它并不真正把重复的元素删除。他是c++中的函数,所以头文件要加 #include<iostream.h>,具体用法如下: int num[100]; unique(num,mun+n)返回的是num去重后的尾地址,之所以说比不真正把重复的元素删除, 其实是,该函数把重复的元素一到后面去了,然后依然保存到了原数组中,然后返回去重后 最后一个元素的地址,因为unique去除的是相邻的重复元素,所以一般用之前都会要排一下序。
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
const int N = 100010;
int a[N];
int b[N];
int dp[N];
int q[N<<2];
int n,d,t;
void pushu(int gen,int l,int r)
{
q[gen]=max(q[gen<<1],q[gen<<1|1]);
}
void build(int gen,int l,int r)
{
if(l==r)
{
q[gen]=0;
return ;
}
int mid=(l+r)>>1;
build(gen<<1,l,mid);
build(gen<<1|1,mid+1,r);
pushu(gen,l,r);
}
int query(int gen,int l,int r,int ll,int rr)
{
if(ll<=l&&r<=rr)
{
return q[gen];
}
int mid=(l+r)>>1;
int cnt=-1;
if(ll<=mid)
cnt=max(cnt,query(gen<<1,l,mid,ll,rr));
if(rr>mid)
cnt=max(cnt,query(gen<<1|1,mid+1,r,ll,rr));
return cnt;
}
void update(int gen,int l,int r,int p,int v)
{
if(l==r)
{
q[gen]=v;
return ;
}
int mid=(l+r)>>1;
if(p<=mid)
update(gen<<1,l,mid,p,v);
else
update(gen<<1|1,mid+1,r,p,v);
pushu(gen,l,r);
}
int main()
{
while(scanf("%d%d",&n,&d)!=EOF)
{
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+1,b+n+1);
int t=unique(b+1,b+n+1)-(b+1);
memset(dp,0,sizeof(dp));
dp[1]=1;
build(1,1,n);
for(int i=1;i<=n;i++)
{
int gen=lower_bound(b+1,b+t+1,a[i])-b;
int l=lower_bound(b+1,b+t+1,a[i]-d)-b;
int r=upper_bound(b+1,b+t+1,a[i]+d)-b-1;
dp[i]=query(1,1,n,l,r)+1;
update(1,1,n,gen,dp[i]);
}
int ans=-1;
for(int i=1;i<=n;i++)
ans=max(ans,dp[i]);
printf("%d\n",ans);
}
return 0;
}