首页 > 其他 > 详细

二分答案三连发

时间:2014-02-09 16:42:26      阅读:364      评论:0      收藏:0      [点我收藏+]

LA3971 Assemble

你有b块钱,给出n个配件的个子的种类,性能和价格,每种类型的配件买一个,价格不超过b,因为有水桶效应,所以电脑的性能取决于性能最低的配件的性能,问你b块钱配的电脑性能最高有多少。

 

按照白书的说法,最大值尽量小,最小值尽量大之类的问题一般都可以用二分答案的方法来结局,这道题就是一道典型的最小值最大问题,所以采用二分答案

 

 

LA3635

 

你请来了F个朋友,一起来分N个圆形的派,每个人得到的必须是一块或者是一块派的一部分,而不是几块派拼在一起的,问你每个人最多能得到多大的派

 

对浮点数的二分,设一个eps,当end-str<eps的时候跳出循环

PS.常量π的值可以用const int PI = acos(-1.0)来得,这样精度比较靠谱

 

LA 3177 Beijing Guards

 

有n个人围城一个圈,每个人想拿ri种物品,要求相邻的两个人不能拿一样的,问最少需要多少种物品

 

当n为偶数的时候非常好处理,只要找到最大的ri+ri-1的和就行了。

当n为奇数的时候可以对所需要的物品数进行二分。

 

第一个人需要r1件物品,设left[i],right[i]分别为第i个人从1~ri,ri+1~p中拿的物品数目,偶数的人尽量拿前面的,奇数的人尽量拿后面的,那么第n个人必定是尽量拿后面的,此时判断时候和r1冲突即可

 

关于二分查找的一些总结:

很多问题都可以用二分来解决,但是根据每次寻找的条件不同,迭代的时候值的变化也会不同,简单总结一下;

1、查找某个元素是否存在

mid = (begin + end) / 2

if(mid < v) begin = mid + 1;

if(mid > v) end = mid – 1;

if(mid == v) return v;

2、查找不小于v的最小值

mid = (end + begin) / 2

if(mid < v) begin = mid + 1; else end = mid;

3、查找大于v的最小值

mid = (end + begin) / 2

if(mid <= v) begin = mid + 1; else end = mid;

3、查找满足条件的v的最小值

mid = (begin + end) / 2

if(ok(mid)) end = mid; else begin = mid – 1;

4、查找满足条件的v的最大值

mid = begin + (end – begin +1) / 2

if(ok(mid)) begin = mid; else end = mid – 1;

可以发现在寻找满足条件的v的最大值的时候mid取值和其他时候不一样,因为在处理两个相邻的数字的时候优先尝试大的那个,mid这样取可以保证一定比begin大,不然有可能会进入死循环

 

这里顺便总结一下STL中lower_bound和upper_bound 的用法

 

原型如下

 

函数有两种重载,区别就是多了一个最后的比较函数,默认使用类的operator<,也可以自定义cmp函数,函数接受两个迭代器,分别表示一段范围,注意last表示的是最后一个元素的后一个,返回一个指向所需元素的迭代器,失败了返回last

二分答案三连发

原文:http://www.cnblogs.com/rolight/p/3541426.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!