跳石头

传送门

分析

这个题题目问你最短距离的最大距离是不是很难理解(给个面子嘛)。
那么我们可以理解为求出能使题目成立的最小的跳跃距离。
所以我们这里可以“分类讨论”一下答案。

大佬的话

这里是引用我们把这个方法叫做“二分答案”。顾名思义,它用二分的方法枚举答案,并且枚举时判断这个答案是否可行。但是,二分并不是在所有情况下都是可用的,使用二分需要满足两个条件。一个是有界,一个是单调。

二分答案应该是在一个单调闭区间上进行的。也就是说,二分答案最后得到的答案应该是一个确定值,而不是像搜索那样会出现多解。二分一般用来解决最优解问题。刚才我们说单调性,那么这个单调性应该体现在哪里呢?

可以这样想,在一个区间上,有很多数,这些数可能是我们这些问题的解,换句话说,这里有很多不合法的解,也有很多合法的解。我们只考虑合法解,并称之为可行解。考虑所有可行解,我们肯定是要从这些可行解中找到一个最好的作为我们的答案, 这个答案我们称之为最优解。

最优解一定可行,但可行解不一定最优。我们假设整个序列具有单调性,且一个数x为可行解,那么一般的,所有的x’(x’<x)都是可行解。并且,如果有一个数y是非法解,那么一般的,所有的y’(y’>y)都是非法解。

那么什么时候适用二分答案呢?注意到题面:使得选手们在比赛过程中的最短跳跃距离尽可能长。如果题目规定了有“最大值最小”或者“最小值最大”的东西,那么这个东西应该就满足二分答案的有界性(显然)和单调性(能看出来)。

那么我们就可以开始构建代码了。

#include<bits/stdc++.h>
using namespace std;
int len,mid,n,m,s,ans;
int rr,ll,now;
int f[50020];
int main()
{
	cin>>len>>n>>m;
	for(int i=1;i<=n;i++) cin>>f[i];
	rr=len,ll=0;//第一次定范围,首和尾
	while(ll<=rr)
	{
		now=0;//当前成立的石头的下标
		s=0;//石子移走数量
		mid=(ll+rr)>>1;//(位运算) 枚举最短长度
		for(int i=1;i<=n;i++)
		{
			if(f[i]-f[now]<mid) s++;//如果比现在最短距离还短,移走数量+1
			else now=i;//跳到第i个石头,mid因为是最小的跳跃长度
		}
		if(s<=m) ans=mid,ll=mid+1;//如果比当前最小距离小的数量大于标准,范围缩到右边
		if(s>m) rr=mid-1; //如果比当前最小距离小的数量小于标准的,范围缩到左边
	}
	cout<<ans;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值