zoj Special Subsequence 3349 (DP+线段树优化) 好题***

来源:互联网 发布:工业机器人编程原理 编辑:程序博客网 时间:2024/05/22 14:56
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 21 4 3 6 55 01 2 3 4 5

Sample Output

31
//知道它是个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);elseupdate(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;}

 
0 0
原创粉丝点击