题目链接:hdu 4521

  本是 dp 的变形,却能用线段树,感觉好强大。

  由于 n 有 10^5,用普通的 dp,算法时间复杂度为 O(n2),肯定会超时。所以用线段树进行优化。线段树维护的是区间内包含某点的最大满足条件的长度,叶子节点以该元素结尾,最长长度。至于相邻两项隔 d 个位置,求 dp[i] 时,我们只把 dp[i - d - 1] 更新至线段树中,然后在这颗线段树中找最大的个数。

  具体来说,就是把序列 S 的值 Ai 作为线段树叶子下标,以 Ai 结尾的 LIS 长度(即经典算法里的 dp[i])作为叶子结点的值,然后对每个 Ai,查询 0 ~ Ai - 1 的最大的 LIS 长度(也就是 dp[]),这个用线段树实现可以很快地得到结果;至于更新时,不能每遍历到一个就直接更新,因为这样子的话 A[i - d] ~ A[i - 1] 会被加入到线段树中,它们对 A[i] 无任何作用,却会对线段树的查询结果有干扰,因此我们在对每一个 Ai 进行查询(即计算出对应的 dp[i])前,就只把 A[i - d - 1] 即 dp[i - d - 1] 加入到线段树中即可,这个操作是很关键的。理清思路后,就是线段树的单点更新、区间查询了。

  因为我写线段树习惯从 1 开始,所以对所有元素都 +1 了。

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define root int rt, int l, int r
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define makemid int mid = l + r >> 1
const int N = ; int len[N << ]; void build(root) {
len[rt] = ;
if(l == r) return ;
makemid;
build(lson);
build(rson);
} inline void pushup(int rt) {
len[rt] = max(len[rt << ], len[rt << | ]);
} int pos, val;
void update(root) {
if(l == r) {
len[rt] = max(len[rt], val);
return ;
}
makemid;
if(pos <= mid) update(lson);
else update(rson);
pushup(rt);
} int ql,qr;
int query(root) {
if(ql <= l && r <= qr) return len[rt];
makemid;
int res = ;
if(ql <= mid) res = max(res, query(lson));
if(qr > mid) res = max(res, query(rson));
return res;
} int dp[N], num[N]; int main() {
int n,d;
while(~scanf("%d%d",&n,&d)) {
int mm = , ans = ;
for(int i = ; i <= n; ++i) {
scanf("%d",num + i);
++num[i];
mm = max(mm, num[i]);
}
build(,,mm);
for(int i = ; i <= n; ++i) {
if(i - d - >= ) { //这是关键,只把 i-d-1 前面的更新至线段树中
pos = num[i - d - ];
val = dp[i - d - ];
update(,,mm);
}
if(num[i] == ) dp[i] = ;
else {
ql = ;
qr = num[i] - ;
dp[i] = query(,,mm) + ;
}
ans = max(ans, dp[i]);
}
printf("%d\n",ans);
}
return ;
}

hdu 4521 小明系列问题——小明序列(线段树 or DP)的更多相关文章

  1. HDU 4521 小明系列问题——小明序列 (线段树维护DP)

    题目地址:HDU 4521 基本思路是DP.找前面数的最大值时能够用线段树来维护节省时间. 因为间隔要大于d. 所以能够用一个队列来延迟更新,来保证每次询问到的都是d个之前的. 代码例如以下: #in ...

  2. hdu 4521 小明系列问题——小明序列 线段树+二分

    小明系列问题——小明序列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Pro ...

  3. hdu 4521 小明系列问题——小明序列(线段树+DP或扩展成经典的LIS)

    小明系列问题--小明序列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Tot ...

  4. 小明系列问题――小明序列(LIS)

    小明系列问题――小明序列 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit ...

  5. hdu----(4521)小明系列问题——小明序列

    小明系列问题——小明序列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tota ...

  6. 小明系列问题——小明序列(Lis 相距大于d的单调上升子序列)

    小明系列问题——小明序列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Tot ...

  7. 2018.07.08 hdu4521 小明系列问题——小明序列(线段树+简单dp)

    小明系列问题--小明序列 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Proble ...

  8. Snacks HDU 5692 dfs序列+线段树

    Snacks HDU 5692 dfs序列+线段树 题意 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充, ...

  9. HDU 4521 小明系列问题——小明序列 (线段树 单点更新)

    题目连接 Problem Description 大家都知道小明最喜欢研究跟序列有关的问题了,可是也就因为这样,小明几乎已经玩遍各种序列问题了.可怜的小明苦苦地在各大网站上寻找着新的序列问题,可是找来 ...

随机推荐

  1. HDU 4707:Pet

    Pet Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis ...

  2. YTU 3007: 顺序串的基本运算

    3007: 顺序串的基本运算 时间限制: 1 Sec  内存限制: 128 MB 提交: 1  解决: 1 题目描述 编写一个程序,实现顺序串的各种基本运算,主函数已给出,请补充每一种方法. 1.建立 ...

  3. 我的CSS样式记事本(1)

    文本 行高: line-height 对齐方式: text-align 字符间距: letter-spacing 文本修饰: text-decoration字体 设置字体所有: font 字体类型: ...

  4. 20150618_Andriod _set Dialog_弹出式菜单

    参考地址: http://blog.csdn.net/zhyl8157121/article/details/8169172                   http://blog.csdn.ne ...

  5. Balance

    Balance Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 11947 Accepted: 7464 Description ...

  6. Netfilter/iptables防火墙

    http://os.51cto.com/art/201107/273443.htm [51CTO独家特稿]Linux系统管理员们都接触过Netfilter/iptables,这是Linux系统自带的免 ...

  7. Winform自定义分页控件的实现

    实现效果 有点丑陋 但是功能是没问题的 测试过 实现思路 先创建一个用户控件 代码实现 public partial class PagerControl : UserControl { ; /// ...

  8. Java中通过JDBC远程连接Oracle数据库

    通过jdbc连接数据库,拢共分三步: 第一步:下载一个JDBC的驱动,然后把jar包扔到项目里并add to build path: 第二步:去本地oracle文件夹下找到“TNSNAMES.ORA” ...

  9. zoj 3557 How Many Sets II

    How Many Sets II Time Limit: 2 Seconds      Memory Limit: 65536 KB Given a set S = {1, 2, ..., n}, n ...

  10. SQL Server中常用的SQL语句

    1.概述 名词 笛卡尔积.主键.外键 数据完整性 实体完整性:主属性不能为空值,例如选课表中学号和课程号不能为空 参照完整性:表中的外键取值为空或参照表中的主键 用户定义完整性:取值范围或非空限制,例 ...