题目大意

给定区间[0,L],在区间内给定N个数,加上区间的端点总共N+2个值。这N+2个数相邻的两个数之间有一个差值delta[i],现在可以从除去端点之外的这N个数中删除M个,使得剩余的N+2-M个数相邻数的最小差值最大。求这N+2-M个数相邻数的最小差值的最大值。

题目分析

典型的最大化最小值问题,最大化/最小化 最大值/最小值/平均值的问题,通常可以考虑使用二分法。如果对于一个数x,判断x是否满足题目要求的时间复杂度不高,那么可以尝试枚举x(当然如果x满足要求,那么所有比x大(或者所有比x小)的数都满足要求,则可以使用二分法枚举)。 
    题目中位置0和位置L处的数字不能删除,假设从N个数中删除M个,可以使得相邻数字的最小差值为x。那么就从位置0开始考虑,寻找下一个和当前数字差值小于x的数a,将a删除... 直到删除数字为M个或者到达N+1的位置停止。若还没删除M个就已经到达了N+1的位置,则说明必定可以使得相邻数字的最小差值大于等于x;若已经删除了M个,则考虑剩余的那些数字中的相邻差值是否小于x,若小于,则说明不满足要求。 
    此题关键的一点是位置0处的数字不能删除,这样就可以从位置0开始考虑,用类似贪心的方法,通过最小距离大于等于x来覆盖到N+1。

实现(c++)

#include<stdio.h>
#include<cmath>
#include<algorithm>
using namespace std;
#define MAX_N 50005
int gDist[MAX_N];
//判断能否从n个数字中删除m个,使得相邻最小距离大于等于 min_dist
bool CanSet(int n, int m, int min_dist){
int last_i = 0;
int i = 1;
int c = 0;
while (i <= n && c < m){
if (gDist[i] - gDist[last_i] < min_dist){
c++;
}else
last_i = i;
i++;
} if (c == m){
if (gDist[i] - gDist[last_i] < min_dist) //注意考虑 i和 last_i
return false; for (; i <= n; i++)
if (gDist[i + 1] - gDist[i] < min_dist)
return false;
}
return true;
}
int main(){
int l, n, m;
while (scanf("%d %d %d", &l, &n, &m) != EOF){
gDist[0] = 0;
gDist[n + 1] = l;
for (int i = 1; i <= n; i++){
scanf("%d", gDist + i);
}
sort(gDist, gDist + n + 2);
int beg = 1, end = l + 1; //二分法,左闭右开!! 故用 l+1
while (beg < end){
int mid = (beg + end) / 2;
if (CanSet(n, m, mid))
beg = mid + 1;
else
end = mid;
}
printf("%d\n", beg - 1);
}
return 0;
}

poj_3258 二分法的更多相关文章

  1. C语言两种查找方式(分块查找,二分法)

    二分法(必须要保证数据是有序排列的):   分块查找(数据有如下特点:块间有序,块内无序):    

  2. poj3122-Pie(二分法+贪心思想)

    一,题意: 有f+1个人(包括自己),n块披萨pie,给你每块pie的半径,要你公平的把尽可能多的pie分给每一个人 而且每个人得到的pie来自一个pie,不能拼凑,多余的边角丢掉.二,思路: 1,输 ...

  3. 二分法&三分法

    ural History Exam    二分 #include <iostream> #include <cstdlib> using namespace std; //二分 ...

  4. [No000087]Linq排序,SortedList排序,二分法排序性能比较

    using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; ...

  5. [PHP]基本排序(冒泡排序、快速排序、选择排序、插入排序、二分法排序)

    冒泡排序: function bubbleSort($array){ $len=count($array); //该层循环控制 需要冒泡的轮数 for($i=1;$i<$len;$i++){ / ...

  6. iOS常见算法(二分法 冒泡 选择 快排)

    二分法: 平均时间复杂度:O(log2n) int halfFuntion(int a[], int length, int number)  { int start = 0; int end = l ...

  7. java简单的二分法排序

    二分法排序的思路:数据元素要按顺序排列,对于给定值 x,从序列的中间位置开始比较,如果当前位置值等于 x,则查找成功:若 x 小于当前位置值,则在数列的前半段中查找:若 x 大于当前位置值则在数列的后 ...

  8. 使用二分法查找mobile文件中区号归属地

    #!/usr/bin/env python #coding:utf-8 ''' Created on 2015年12月8日 @author: DL @Description: 使用二分法查找mobil ...

  9. Atitit 迭代法  “二分法”和“牛顿迭代法 attilax总结

    Atitit 迭代法  "二分法"和"牛顿迭代法 attilax总结 1.1. ."二分法"和"牛顿迭代法"属于近似迭代法1 1. ...

随机推荐

  1. POI生成EXCEL,公式不自动执行的有关问题

    POI生成EXCEL,公式不自动执行的问题 场景:POI读取Excel模板. 当使用POI操作Excel时,发现由POI生成的公式能够在打开Excel是被执行, 而事先手工写入Excel模板文件的公式 ...

  2. 正确配置Linux系统ulimit值的方法

    在Linux下面部署应用的时候,有时候会遇上Socket/File: Can’t open so many files的问题:这个值也会影响服务器的最大并发数,其实Linux是有文件句柄限制的,而且L ...

  3. Ajax-ajax实例3-动态树形列表

    项目结构: 项目演示: 技术要点: 1.3.2 技术要点在基本原理的介绍中,了解到通过在父节点内动态创建子节点,并利用样式表缩进完成树形列表的基本框架.除了这一点外,还有下面一些问题需要考虑.1 .将 ...

  4. js类型转换 之 转数字类型

    手动将各类型 转换成 数字类型 JS提供了三种方法: Number(object); parseInt(string, radix); parseFloat(string, radix). 三种方法具 ...

  5. CSS控制显示图片的一部分

    使用情形:防止反复请求图片资源,我们经常采用一张图片多种效果或内容显示. 假设我有纸张竖直方向的一张图片,竖直y轴方向分别是字母:A,B,C.... 现在分别要显示A.B.C 等字母,我们的CSS可以 ...

  6. 机器学习性能评估指标(精确率、召回率、ROC、AUC)

    http://blog.csdn.net/u012089317/article/details/52156514 ,y^)=1nsamples∑i=1nsamples(yi−y^i)2

  7. 【转】【C++】C++ 中的线程、锁和条件变量

    线程 类std::thread代表一个可执行线程,使用时必须包含头文件<thread>.std::thread可以和普通函数,匿名函数和仿函数(一个实现了operator()函数的类)一同 ...

  8. 第三百零九节,Django框架,models.py模块,数据库操作——F和Q()运算符:|或者、&并且——queryset对象序列化

    第三百零九节,Django框架,models.py模块,数据库操作——F()和Q()运算符:|或者.&并且 F()可以将数据库里的数字类型的数据,转换为可以数字类型 首先要导入 from dj ...

  9. Climbing Stairs爬楼梯——动态规划

    题目描写叙述: 初阶:有n层的台阶,一開始你站在第0层,每次能够爬两层或者一层. 请问爬到第n层有多少种不同的方法? 进阶:假设每次能够爬两层.和倒退一层,同一个位置不能反复走,请问爬到第n层有多少种 ...

  10. Oracle查询优化-使用字符串

    --1.遍历字符串 --1.1.建立测试视图 CREATE OR REPLACE VIEW V AS SELECT '天天向上' AS 汉字,'TTXS' AS 首拼 FROM DUAL; --要求每 ...