zoj 3349 dp + 线段树优化

题目:给出一个序列,找出一个最长的子序列,相邻的两个数的差在d以内。

 1 /*
 2 线段树优化dp
 3 dp[i]表示前i个数的最长为多少,则dp[i]=max(dp[j]+1) abs(a[i]-a[j])<=d
 4 复杂度为O(n ^ 2)
 5 利用线段树优化,线段树保存区间最大值。离散化后便可求出,还要注意 对于叶子节点保存的即为dp的值,每次更改即可,开始一直累加。。。。。
 6 */
 7 #include <iostream>
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cmath>
11 #include <algorithm>
12 
13 using namespace std;
14 #define lson l,m,rt<<1
15 #define rson m + 1, r, rt<<1|1
16 const int maxn = 1e5 + 5;
17 int s[maxn];
18 int n, d;
19 int san[maxn], tot;
20 int sum[maxn << 2];
21 void pushUp(int rt){
22     sum[rt] = max(sum[rt<<1], sum[rt<<1|1]);
23 }
24 void update(int pos, int c, int l, int r, int rt){
25     if (l == r){
26         sum[rt] = c;//注意
27         return ;
28     }
29     int m = (l + r) >> 1;
30     if (pos <= m) update(pos, c, lson);
31     else update(pos, c, rson);
32     pushUp(rt);
33 }
34 int query(int L, int R, int l, int r, int rt){
35     if (L <= l && R >= r){
36         return sum[rt];
37     }
38     int m = (l + r) >> 1;
39     int ret = 0;
40     if (L <= m) ret = query(L, R, lson);
41     if (R > m) ret = max(ret, query(L, R, rson));
42     return ret;
43 }
44 int main(){
45     while (~scanf("%d%d", &n, &d)){
46         tot = 0;
47         for (int  i = 1; i <= n; ++i){
48             scanf("%d", &s[i]);
49             san[tot++] = s[i];
50         }
51         sort(san, san + tot);
52         tot = unique(san, san + tot) - san;
53 
54         memset(sum, 0, sizeof(sum));
55         int ans = 0;
56         for (int i = 1; i <= n; ++i){
57             int pos = lower_bound(san, san + tot, s[i]) - san + 1;
58             int l = lower_bound(san, san + tot, s[i] - d) - san + 1;
59             int r = upper_bound(san, san + tot, s[i] + d) - san;
60             int que = query(l, r, 1, tot, 1) + 1;
61             //cout << " l = " << l << " r = " << r << endl;
62             ans = max(ans, que);
63             //cout << " ans = " << ans << endl;
64             update(pos, que, 1, tot, 1);
65         }
66         printf("%d\n", ans);
67     }
68     return 0;
69 }

 

posted @ 2013-11-10 13:10  Missa  阅读(671)  评论(0编辑  收藏  举报