POJ3258-River Hopscotch-二分+贪心【最小值最大化】

给你L,n,m
L是一条路总长度
n是路上n个石头
m是要移走m个石头(第一个和最后一个石头不能移走)
 

设X为剩下的n-m个石头里,石头之间相邻最近的距离


求这个X的最大值


二分X,对于每个X,我们贪心,从a[0]开始,把a[i]+x范围内的j个石头都移掉,接下来从i+j+1开始重复移石头。

如果最后移动的石头超过了m个,那么说明 这个X太大了答案取【left,mid-1】,如果小于等于m个,那么说明答案在[mid,right]之间


#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std; 
const double pi=acos(-1.0);
double eps=0.000001; 


	int n,m;
int tm[100005]; 
int bin(int x)
{
	int i;
	int num=0;
	for (i=0;i<=n+1;i++)
	{
		int j=i+1;
		while(tm[j]-tm[i]<x&&j<=n) 
			j++;
		num+=j-i-1;
		i=j-1;
	}
	return num; 
 
}
int main()
{
	int i;
	int ll;
	cin>>ll;
	cin>>n>>m;
	int minn=2147483647;
	for (i=1;i<=n;i++)
	{
		scanf("%d",&tm[i]); 
	}    
	sort(tm+1,tm+1+n);
	tm[0]=0;
	tm[n+1]=ll;
	int l=0;
	int r=ll;
	int ans=-1; 
	while(l<=r)
	{ 
		if (r-l<=1)
		{
 			if (bin(r)== m)
				ans =r;
			else 
				ans=l;
			break;
		}
		int mid=(l+r)>>1;
		int ret=bin(mid); 
		if (ret<=m)
			l=mid; 
		else
			if (ret>m)
			r=mid-1;
		 
	 
	}
	printf("%d\n",ans );
	return 0;
	
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值