P2678 跳石头题解
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#define M(a) memset(a,127,sizeof a)
using namespace std;
int i,L,N,M,a[]; int check(int dist){
int i,last=,cnt=;
for(i=;i<=N;i++){
if(a[i]-last<dist)cnt++;
else last=a[i];
}
if(L-last<dist)cnt++;
return cnt<=M;
} int main(){
scanf("%d %d %d",&L,&N,&M);
for(i=;i<=N;i++)scanf("%d",a+i);
sort(a+,a++N);
int log=,hi=L+,mid;
while(log+<hi){
mid=(log+hi)/;
if(check(mid))log=mid;
else hi=mid;
}
printf("%d\n",log);
}
先声明一下这个涉及版权问题因为这个奆佬讲的很详细很好我自愧不如所以直接复制粘贴如果本人认为侵权立刻删除
讲的太好了
作者如下:
作者: ShawnZhou 更新时间: 2017-08-30 17:10 在Ta的博客查看 392
这道题如果要使用暴力搜索直接求解会严重超时。实际上,我们可以发现,这个所谓的最短跳跃距离显然不能超过一个范围,而这个范围题目上已经给了出来。也就是说,答案是有一个确定的范围限制的,我们就可以考虑一种另外的方法去解决——枚举答案,并去验证答案是否可行。
实际上,枚举答案有时候也会超时。这就好比说你要从一本英汉词典上查一个单词,你从头到尾一页一页的翻着找,这样找可以保证一定能找到,但是最坏情况你要把整本词典都翻一遍,那就麻烦了。
有什么改进的方法吗?当然有。
考虑把这个词典从中间分开,看一下中间那一页的主要单词都是啥,然后去判断我要找的单词应该在左半部分还是右半部分,再去那一部分考虑怎么找就好了。同样的,在另一部分也是要进行划分并且判断的操作。这样一直进行下去,便能很快的找到答案,而且根本不需要翻过整个词典来。
可以证明,如果一页一页的找,最多要找n次,但是用这个方法,最多找floor(log2n)次。
我们把这个方法叫做“二分答案”。顾名思义,它用二分的方法枚举答案,并且枚举时判断这个答案是否可行。但是,二分并不是在所有情况下都是可用的,使用二分需要满足两个条件。一个是有界,一个是单调。
二分答案应该是在一个单调闭区间上进行的。也就是说,二分答案最后得到的答案应该是一个确定值,而不是像搜索那样会出现多解。二分一般用来解决最优解问题。刚才我们说单调性,那么这个单调性应该体现在哪里呢?
可以这样想,在一个区间上,有很多数,这些数可能是我们这些问题的解,换句话说,这里有很多不合法的解,也有很多合法的解。我们只考虑合法解,并称之为可行解。考虑所有可行解,我们肯定是要从这些可行解中找到一个最好的作为我们的答案, 这个答案我们称之为最优解。
最优解一定可行,但可行解不一定最优。我们假设整个序列具有单调性,且一个数x为可行解,那么一般的,所有的x'(x'<x)都是可行解。并且,如果有一个数y是非法解,那么一般的,所有的y'(y'>y)都是非法解。
那么什么时候适用二分答案呢?注意到题面:使得选手们在比赛过程中的最短跳跃距离尽可能长。如果题目规定了有“最大值最小”或者“最小值最大”的东西,那么这个东西应该就满足二分答案的有界性(显然)和单调性(能看出来)。
那就好办了。我们二分跳跃距离,然后把这个跳跃距离“认为”是最短的跳跃距离,然后去以这个距离为标准移石头。使用一个judge判断这个解是不是可行解。如果这个解是可行解,那么有可能会有比这更优的解,那么我们就去它的右边二分。为什么去右边?答案是,这个区间是递增的 ,而我们求的是最短跳跃距离的最大值,显然再右边的值肯定比左边大,那么我们就有可能找到比这更优的解,直到找不到,那么最后找到的解就有理由认为是区间内最优解。反过来,如果二分到的这个解是一个非法解,我们就不可能再去右边找了。因为性质,右边的解一定全都是非法解。那么我们就应该去左边找解。整个过程看起来很像递归,实际上,这个过程可以递归写, 也可以写成非递归形式,我个人比较喜欢使用非递归形式。
下一个问题,这个judge怎么实现呢?judge函数每个题有每个题的写法,但大体上的思想应该都是一样的——想办法检测这个解是不是合法。拿这个题来说,我们去判断如果以这个距离为最短跳跃距离需要移走多少块石头,先不必考虑限制移走多少块,等全部拿完再把拿走的数量和限制进行比对,如果超出限制,那么这就是一个非法解,反之就是一个合法解,很好理解吧。
可以去模拟这个跳石头的过程。开始你在i(i=0)位置,我在跳下一步的时候去判断我这个当前跳跃的距离,如果这个跳跃距离比二分出来的mid小,那这就是一个不合法的石头,应该移走。为什么?我们二分的是最短跳跃距离,已经是最短了,如果跳跃距离比最短更短岂不是显然不合法,是这样的吧。移走之后要怎么做?先把计数器加上1,再考虑向前跳啊。去看移走之后的下一块石头,再次判断跳过去的距离,如果这次的跳跃距离比最短的长,那么这样跳是完全可以的,我们就跳过去,继续判断,如果跳过去的距离不合法就再拿走,这样不断进行这个操作,直到i = n+1,为啥是n+1?河中间有n块石头,显然终点在n+1处。(这里千万要注意不要把n认为是终点,实际上从n还要跳一步才能到终点)。
模拟完这个过程,我们查看计数器的值,这个值代表的含义是我们以mid作为答案需要移走的石头数量,然后判断这个数量 是不是超了就行。如果超了就返回false,不超就返回true。
整道题我已经说完了。。。如果实在难以理解,请看代码。
P2678 跳石头题解的更多相关文章
- [NOIP2015提高&洛谷P2678]跳石头 题解(二分答案)
[NOIP2015提高&洛谷P2678]跳石头 Description 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选择好了两块岩石作为比赛起点和终点.在起点和终点之 ...
- 洛谷 p2678 跳石头 题解
一道裸的二分答案 如果不会分治的去找dalao吧,本蒟蒻只会二分 不知道二分答案的看这里 这位dalao解释的很详细其实只是随便找了一个 那里面貌似也有这个题的题解,但我还是要写(才不是应付老师) 关 ...
- 洛谷P2678跳石头题解
题目 这个题也是一个很经典的题了.其主要思想也是二分答案,原因就是题目中只要出现最大值最小或最小值最大,这种描述十有八九就是二分答案. 这个题原题也是让我们求最短的跳跃距离的最大值. 显而易见,最大值 ...
- 解题报告:luogu P2678 跳石头
题目链接:P2678 跳石头 很简单的二分查找,可悲的是我并不会. 不过题解贴心的写得很清楚(学会了套路) 二分一次判断一次,复杂度是\(O(nlogl)\),可以通过此题. \(Code:\) #i ...
- 洛谷 P2678 跳石头
题目背景 一年一度的"跳石头"比赛又要开始了! 题目描述 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选择好了两块岩石作为比赛起点和终点.在起点和终点之间 ...
- P2678 跳石头(二分答案)
P2678 跳石头 题目背景 一年一度的“跳石头”比赛又要开始了! 题目描述 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选择好了两块岩石作为比赛起点和终点.在起点和终点之间 ...
- Luogu P2678 跳石头(二分)
P2678 跳石头 题意 题目背景 一年一度的"跳石头"比赛又要开始了! 题目描述 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选择好了两块岩石作为比赛起 ...
- [NOIP2015] 提高组 洛谷P2678 跳石头
题目背景 一年一度的“跳石头”比赛又要开始了! 题目描述 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选择好了两块岩石作为比赛起点和终点.在起点和终点之间,有 N 块岩石(不 ...
- P2678 跳石头---(二分答案)
题目背景 一年一度的“跳石头”比赛又要开始了! 题目描述 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选择好了两块岩石作为比赛起点和终点.在起点和终点之间,有 NNN 块岩石 ...
随机推荐
- cf997C. Sky Full of Stars(组合数 容斥)
题意 题目链接 \(n \times n\)的网格,用三种颜色染色,问最后有一行/一列全都为同一种颜色的方案数 Sol Orz fjzzq 最后答案是这个 \[3^{n^2} - (3^n - 3)^ ...
- CSS选择器:子选择符号
<html> <head> <style type="text/css"> .class>h2{color:red} </style ...
- IIS下配置跨域设置Access-Control-Allow-Origin
设置Access-Control-Allow-Origin 打开IIS,找到“HTTP响应标头”点进去, 在右侧可以看到添加,然后添加如下标头即可 Access-Control-Allow-Heade ...
- 从文本中提取图片路径(java 解析富文本处理 img 标签)
很多项目都需要到富文本来添加内容,就好比新闻啊,旅游景点之类的,都需要使用富文本去添加数据,然而怎么我这边就发现了两个问题 怎样将富文本的图片的 src 获取出来? 方法一: 利用正则表达式: pub ...
- 前端 CSS预处理器Less
引文 Less是一种动态的样式语言.Less扩展了CSS的动态行为,比如说,设置变量(Variables).混合书写模式(Mixins).操作(Operations)和功能(Functions)等等, ...
- ORACLE中Scalar subquery Caching的hash table大小测试浅析
前阵子总结了这篇"ORACLE当中自定义函数性优化浅析"博客,里面介绍了标量子查询缓存(scalar subquery caching),如果使用标量子查询缓存,ORACLE会 ...
- spring4笔记----报错publicid systemid之间要有空格的解决方法
<?xml version="1.0" encoding="GBK"?> <beans xmlns:xsi="http://www. ...
- C#面向对象 1
using System; using System.Collections.Generic; using System.Collections; using System.Linq; using S ...
- SQL Server 执行计划解析
前置说明: 本文旨在通过一个简单的执行计划来引申并总结一些SQL Server数据库中的SQL优化的关键点,日常总结,其中的概念介绍中有不足之处有待补充修改,希望大神勘误. SQL语句如下: SELE ...
- AspNet MVC中使用Hangfire执行定时任务
Hangfire在Aspnet中执行定时任务: 第一步: NuGet中加入Hangfire包 第二步: 添加Owin的自启动 第三步.Hangfire的后台控制仪表盘默认情况下只能本地访问,外网访问需 ...