stone
2016-05-18 12:58
232 查看
题目的大概意思是:在一条道路上有N个石头,现在要移走M个石头,问移走之后剩下的石头中的最小的距离最大是多少。
首先,根据题目,以及修改数据发现,如果移走的石头越多,那么答案就会越大。从这里就证明了答案是具有单调性的。根据这一点,那么答案就可以用二分答案的方法来求出。
首先,每一个答案都需要验证需移走的石头数是多少,那么,到底要怎么移动,才能让移走的数量最少呢?
例如样例2 11 14
17 21,先实验移走2个到所有石头间的距离都大于12,可以发现,每一次移动,都是移走当前距离与前面一个小于12的。如果移走的是前面的那一个,就会有一些缺陷:你不知道后面会有哪些石头与它的距离是小于12的,如果距离已经是小于12了,而且是最后一个,那么这一种移动方案也不成立。根据贪心的思想来解释,既然前面的已经达到了这个距离,我再增大这个距离对我也没有什么益处,反而移走当前这一个,后面原本小于12的距离也可能会变得大于12,这样要移走的数量自然就少了。这样就可以得到一个最优方案。所以,自然是这样移动是最好的。
算出来移动的个数之后,就可以判断,如果移走的个数比m大,就证明答案要达到这个距离是不可能的事,自然答案就会比当前测试的答案小。否则就可能比这一个大。注意,在二分的时候,也要注意几点:必须要让二分区间达到(】,即右边的一定不成立,而左边的一定成立,而不是让最左点和最右点都能成立,这样二分出来的答案自然就容易不正确。(CCF给出的数据表示,就算没有这么严格,同样能对;但是,如果数据挑一些很困难的数据,答案自然就错了)最后二分出来的答案自然就是左端点(右端点不成立)。
以下为程序:
最后再说一句,因为二分用递归容易栈溢出(虽然只有50次),所以要用迭代。而且因为可以从起点跳到第一个石头或最后一个石头跳到终点,所以这个也需要算上。
首先,根据题目,以及修改数据发现,如果移走的石头越多,那么答案就会越大。从这里就证明了答案是具有单调性的。根据这一点,那么答案就可以用二分答案的方法来求出。
首先,每一个答案都需要验证需移走的石头数是多少,那么,到底要怎么移动,才能让移走的数量最少呢?
例如样例2 11 14
17 21,先实验移走2个到所有石头间的距离都大于12,可以发现,每一次移动,都是移走当前距离与前面一个小于12的。如果移走的是前面的那一个,就会有一些缺陷:你不知道后面会有哪些石头与它的距离是小于12的,如果距离已经是小于12了,而且是最后一个,那么这一种移动方案也不成立。根据贪心的思想来解释,既然前面的已经达到了这个距离,我再增大这个距离对我也没有什么益处,反而移走当前这一个,后面原本小于12的距离也可能会变得大于12,这样要移走的数量自然就少了。这样就可以得到一个最优方案。所以,自然是这样移动是最好的。
算出来移动的个数之后,就可以判断,如果移走的个数比m大,就证明答案要达到这个距离是不可能的事,自然答案就会比当前测试的答案小。否则就可能比这一个大。注意,在二分的时候,也要注意几点:必须要让二分区间达到(】,即右边的一定不成立,而左边的一定成立,而不是让最左点和最右点都能成立,这样二分出来的答案自然就容易不正确。(CCF给出的数据表示,就算没有这么严格,同样能对;但是,如果数据挑一些很困难的数据,答案自然就错了)最后二分出来的答案自然就是左端点(右端点不成立)。
以下为程序:
#include<stdio.h> #include<stdlib.h> int n,m; int a[100000]; bool _check(int len) { int last=0,move_num=0; for(int i=0;i<n;i++) { if(a[i] - last < len) move_num++; else last = a[i]; } return move_num <= m; } int main() { freopen("stone.in","r",stdin); freopen("stone.out","w",stdout); int l; scanf("%d%d%d",&l,&n,&m); for(int i=0;i<n;i++) scanf("%d",&a[i]); a =l;n++; int lowerlim=0,upperlim=l+1; while(lowerlim+1 < upperlim) { int middle=(upperlim+lowerlim) >> 1; if( _check(middle) ) lowerlim=middle; else upperlim=middle; } printf("%d\n",lowerlim); return 0; } |
相关文章推荐
- 第十二周第三项目——类运算的实现(运算符重载)
- C++ 相关知识总结
- 解决SAP 从nonicode 升级到unicode 环境中 出现 RFC 中文用户名 问题
- 日文 LaTeX 系统介绍 - 最简示例
- C语言编程---socket基础
- 关于烧录工具的总结
- 剑指offer-第九题方法总结
- 多个参数
- fwrite
- HDU 3001 Traveling(状压DP)
- 图像I中亮度值低于特定阈值T的像素点的数目N占总像素数目M的百分比为a
- HDU 2149 Public Sale (巴什博弈)
- FlexPaper实现文档在线浏览(附源码)
- SendKeys.SendWait()BUG解决方法
- MMC/SD卡要点
- [PHP] Yaf框架的简单安装使用
- 学习使用的PL/0编译器增强版PL/0plusplusCompiler(四)使用gdb调试PL0词法分析
- 前端学习方法总结
- hdu 3861 The King’s Problem tarjan+缩点+最小路径覆盖
- HTTP消息头字段