题目链接:https://www.luogu.org/problem/P3957

这道题目我用到了如下算法:

  • 线段树求区间最大值;
  • 二分答案;
  • DP求每一次枚举答案g时是否能够找到 \(\ge k\) 的解法。

我们一开始用 \(x[i]\) 和 \(s[i]\) 来表示到起点的距离以及第 \(i\) 个点的分值。

与此同时我们还要算上我们的起点,它满足性质 \(x[0] = s[0] = 0\) ,我们接下来的判断都是建立在这 \(1 + n\) 个点的基础上的。

check(g)

首先,我们假设 \(g\) 已经确定的情况下,如何判断是否有行走方案能够累计到 \(\ge k\) 。

这一步需要用到DP思想,我们定义状态 \(f[i]\) 表示从起点到第 \(i\) 个点所能够积累的最大分值,那么,状态转移方程为:

\(f[i] = \max( f[j] )\) ,其中 \(j\) 满足 \(x[i]-d-g \le x[j] \le \min( x[i]-1, x[i]-d+g )\)

并且我们可以发现这个范围的 \(j\) 必定在一个连续的区间 \([L, R]\) 内,所以我们可以用二分(lower_boundupper_bound 函数来快速获得 \(L\) 和 \(R\) 。

然后我们需要知道区间 \([L,R]\) 范围内 \(x[j]\) 的最大值,这一步过程我是使用线段树来实现的(因为这里涉及单点更新及区间最值)。

二分答案

在编写完 check(g) 函数之后,我们便可以在区间 \([0, x[n] ]\) 范围内进行二分,进而找到满足要求的最小的答案。

实现代码如下:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 500050;
int n, d, k, x[maxn], s[maxn], f[maxn]; #define lson l, mid, (rt<<1)
#define rson mid+1, r, (rt<<1|1)
#define inf (1<<29)
int maxv[maxn<<2];
void sg_push_up(int rt) {
maxv[rt] = max(maxv[rt<<1], maxv[rt<<1|1]);
}
void sg_build(int l, int r, int rt) {
if (l >= r) maxv[rt] = -inf;
else {
int mid = (l + r) / 2;
sg_build(lson);
sg_build(rson);
sg_push_up(rt);
}
}
void sg_update(int p, int v, int l, int r, int rt) {
if (l == r) maxv[rt] = v;
else {
int mid = (l + r) / 2;
if (p <= mid) sg_update(p, v, lson);
else sg_update(p, v, rson);
sg_push_up(rt);
}
}
int sg_query(int L, int R, int l, int r, int rt) {
if (L <= l && r <= R) return maxv[rt];
int mid = (l + r) / 2, tmp = -inf;
if (L <= mid) tmp = max(tmp, sg_query(L, R, lson));
if (R > mid) tmp = max(tmp, sg_query(L, R, rson));
return tmp;
} bool check(int g) {
sg_build(0, n, 1);
sg_update(0, 0, 0, n, 1);
for (int i = 1; i <= n; i ++) {
f[i] = -inf;
int lid = lower_bound(x, x+i, x[i]-d-g) - x;
int rid = upper_bound(x, x+i+1, min(x[i]-1, x[i]-d+g)) - x - 1;
if (lid <= rid) {
int tmp = sg_query(lid, rid, 0, n, 1);
if (tmp != -inf) {
f[i] = tmp + s[i];
if (f[i] >= k) return true;
sg_update(i, f[i], 0, n, 1);
}
}
}
return false;
} int main() {
cin >> n >> d >> k;
for (int i = 1; i <= n; i ++) cin >> x[i] >> s[i];
int L = 0, R = x[n], res = -1;
while (L <= R) {
int mid = (L + R) / 2;
if (check(mid)) { res = mid; R = mid-1; }
else L = mid + 1;
}
cout << res << endl;
return 0;
}

作者:zifeiy

洛谷P3957 跳房子 题解 二分答案/DP/RMQ的更多相关文章

  1. 2018.09.26洛谷P3957 跳房子(二分+单调队列优化dp)

    传送门 表示去年考普及组的时候失了智,现在看来并不是很难啊. 直接二分答案然后单调队列优化dp检验就行了. 注意入队和出队的条件. 代码: #include<bits/stdc++.h> ...

  2. 洛谷P3957 跳房子(Noip2017普及组 T4)

    今天我们的考试就考到了这道题,在考场上就压根没有思路,我知道它是一道dp的题,但因为太弱还是写不出来. 下来评讲的时候知道了一些思路,是dp加上二分查找的方式,还能够用单调队列优化. 但看了网上的许多 ...

  3. 洛谷 P3957 跳房子 —— 二分答案+单调队列优化DP

    题目:https://www.luogu.org/problemnew/show/P3957 先二分一个 g,然后判断: 由于转移的范围是一个区间,也就是滑动窗口,所以单调队列优化: 可以先令队尾为 ...

  4. P3957 跳房子(二分答案+单调队列优化DP)

    题目链接:https://www.luogu.org/contestnew/show/4468 题目大意:跳房子,也叫跳飞机,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一. 跳房子的游戏规则 ...

  5. 洛谷P3957 跳房子

    普及组的题.....填坑来了. 当年的我一眼二分+DP,现在都佩服起自己来了...... 然后我们就写个二分,在check里面写单调队列优化DP即可. 然后就A了...... #include < ...

  6. 洛谷 P3957 跳房子

    https://www.luogu.org/problemnew/show/P3957 错误记录:1.没开longlong 2. -inf不够小 #include<cstdio> #inc ...

  7. 洛谷 P1800 software_NOI导刊2010提高(06)(二分答案+DP检验)

    P1800 software_NOI导刊2010提高(06) 标签 二分答案 难度 普及/提高- 题目描述 一个软件开发公司同时要开发两个软件,并且要同时交付给用户,现在公司为了尽快完成这一任务,将每 ...

  8. 洛谷NOIp热身赛题解

    洛谷NOIp热身赛题解 A 最大差值 简单树状数组,维护区间和.区间平方和,方差按照给的公式算就行了 #include<bits/stdc++.h> #define il inline # ...

  9. 洛谷 P4072 [SDOI2016]征途 斜率优化DP

    洛谷 P4072 [SDOI2016]征途 斜率优化DP 题目描述 \(Pine\) 开始了从 \(S\) 地到 \(T\) 地的征途. 从\(S\)地到\(T\)地的路可以划分成 \(n\) 段,相 ...

随机推荐

  1. LUOGU P2827 蚯蚓 (noip 2016)

    传送门 解题思路 第一眼以为是一个二叉堆,直接上优先队列60分...后来听ztz11说有单调性,新加入的蚯蚓一定比原先在的蚯蚓长度长,开三个队列,分别放原先的长度,切掉后大的那一半,切掉后小的那一半. ...

  2. 从零起步 系统入门Python爬虫工程师

    从零起步 系统入门Python爬虫工程师 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身没问题,大家看的 ...

  3. layers.py cs231n

    如果有错误,欢迎指出,不胜感激. import numpy as np def affine_forward(x, w, b): 第一个最简单的 affine_forward简单的前向传递,返回 ou ...

  4. Leetcode5.Longest Palindromic Substring最长回文字串

    给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为1000. 示例 1: 输入: "babad" 输出: "bab" 注意: &quo ...

  5. [PHPCMS V9二次开发]自定义字段模型-添加字段类型

    步骤/方法 打开phpcms\modules\content\fields目录,复制文件夹downfiles,并改名为textgroups. 打开phpcms\modules\content\fiel ...

  6. Wireshark抓包常见问题解析(转)

    1. tcp out-of-order(tcp有问题) 解答: 1). 应该有很多原因.但是多半是网络拥塞,导致顺序包抵达时间不同,延时太长,或者包丢失,需要重新组合数据单元 因为他们可能是通过不同的 ...

  7. linux中的用户、群组和权限

     linux中的用户.群组和权限   新建用户natasha,uid为1000,gid为555,备注信息为“master”   groupadd -g 555 natasha useradd -u 1 ...

  8. Directx教程(25) 简单的光照模型(4)

    原文:Directx教程(25) 简单的光照模型(4)      在本篇日志中,我们尝试用不带衰减的点光源来计算漫反射颜色.     前面的三个工程,我们都用的是方向光源(directional li ...

  9. JavaScript中的this关键字的几种用法

    JS 里的 this 在 function 内部被创建 指向调用时所在函数所绑定的对象(拗口) this 不能被赋值,但可以被 call/apply 改变 1. this 和构造函数 function ...

  10. iOS 9 新特性之实现 3D Touch

    http://www.cocoachina.com/ios/20151027/13812.html 10月19号,周末,起床去吃早餐,吃完回来顺便去沃尔玛逛逛,把晚上的菜给买了,逛着逛着就来到了卖苹果 ...