poj_3258 二分法
题目大意
给定区间[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 二分法的更多相关文章
- C语言两种查找方式(分块查找,二分法)
二分法(必须要保证数据是有序排列的): 分块查找(数据有如下特点:块间有序,块内无序):
- poj3122-Pie(二分法+贪心思想)
一,题意: 有f+1个人(包括自己),n块披萨pie,给你每块pie的半径,要你公平的把尽可能多的pie分给每一个人 而且每个人得到的pie来自一个pie,不能拼凑,多余的边角丢掉.二,思路: 1,输 ...
- 二分法&三分法
ural History Exam 二分 #include <iostream> #include <cstdlib> using namespace std; //二分 ...
- [No000087]Linq排序,SortedList排序,二分法排序性能比较
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; ...
- [PHP]基本排序(冒泡排序、快速排序、选择排序、插入排序、二分法排序)
冒泡排序: function bubbleSort($array){ $len=count($array); //该层循环控制 需要冒泡的轮数 for($i=1;$i<$len;$i++){ / ...
- iOS常见算法(二分法 冒泡 选择 快排)
二分法: 平均时间复杂度:O(log2n) int halfFuntion(int a[], int length, int number) { int start = 0; int end = l ...
- java简单的二分法排序
二分法排序的思路:数据元素要按顺序排列,对于给定值 x,从序列的中间位置开始比较,如果当前位置值等于 x,则查找成功:若 x 小于当前位置值,则在数列的前半段中查找:若 x 大于当前位置值则在数列的后 ...
- 使用二分法查找mobile文件中区号归属地
#!/usr/bin/env python #coding:utf-8 ''' Created on 2015年12月8日 @author: DL @Description: 使用二分法查找mobil ...
- Atitit 迭代法 “二分法”和“牛顿迭代法 attilax总结
Atitit 迭代法 "二分法"和"牛顿迭代法 attilax总结 1.1. ."二分法"和"牛顿迭代法"属于近似迭代法1 1. ...
随机推荐
- 【WPF】BusyIndicator做Loading遮罩层
百度了一下,粗略看了几个国内野人的做法,花了时间看下去感觉不太好用(比如有Loading居然只是作为窗体的一个局部控件的,没法全屏遮罩,那要你有何用?),于是谷歌找轮子去. 好用的轮子:http:// ...
- java.lang.OutOfMemoryError: Java heap space 解决方法
从网上抄过来的,因为经常碰到这个问题,记录一下. java.lang.OutOfMemoryError: Java heap space 解决方法 这个问题的根源是jvm虚拟机的默认Heap大小是64 ...
- iOS边练边学--(Quartz2D)图片裁剪,带圆环的裁剪
一.图片裁剪,示意图 二.带圆环的图片裁剪示意图
- JavaScript(一):JavaScript简介
一.什么是JavaScript JavaScript是一种具有面向对象能力的.解释性的程序设计语言.更具体一点,它是基于对象和事件驱动并具有相对安全性的客户端脚本语言.因为他不需要在一个语言环境下运行 ...
- 20个优秀的JavaScript 键盘事件处理库
键盘事件是 Web 开发中最常用的事件之一,通过对键盘事件的捕获和处理可以提高网站的易用性和交互体验.下面,我们向大家介绍收集的20款优秀的 JavaScript 键盘事件处理库,帮助开发人员轻松处理 ...
- 【转】MFC 字体LOGFONT
Windows的字体LOGFONT LOGFONT是Windows内部字体的逻辑结构,主要用于设置字体格式,其定义如下:typedef struct tagLOGFONTA{ LONG ...
- C++ 接口(抽象类)
C++ 接口(抽象类)接口描述了类的行为和功能,而不需要完成类的特定实现. C++ 接口是使用抽象类来实现的,抽象类与数据抽象互不混淆,数据抽象是一个把实现细节与相关的数据分离开的概念. 如果类中至少 ...
- vs2013+MVC3.0+EasyUI的ComboBox联动使用(二)
vs2013+MVC3.0+EasyUI的ComboBox联动使用(二) 简单介绍:在vs2013(.net4.0)中使用MVC3.0对于EasyUI中ComboBox的联动使用. 载入Comb ...
- R语言低级绘图函数-grid
grid 函数用来在一张图表上添加网格线, 基本用法:默认在添加刻度线的地方添加网格线 plot(1:5, 1:5, xlim = c(0,6), ylim = c (0,6), type = &qu ...
- Fastqc 能够识别的碱基编码格式
Fastqc 能够自动识别序列的碱基编码格式,我查看一下源代码,发现是碱基编码格式一共分为 1)sanger/illumina 1.9 2) illumina 1.3 3) illumina 1.5 ...