码迷,mamicode.com
首页 > 其他好文 > 详细

二分题目总结(未完待续)

时间:2014-11-29 14:24:17      阅读:103      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   io   ar   color   os   sp   for   

二分的用处太大了,不管是求简单的方程,还是求最优解方面都是不错的解题思想。

      只要在线性,顺序或者有序的数据里就可以用二分来找最优的答案,而且时间平均都是O(log2 n)。题目中好像是HDU 4190吧,这题的限时是10000ms,而用二分做才用时1000ms,其优点可想而知。

       不过就像《编程珠玑》中说的一样,虽然二分思路及其做法很爽,但是编写二分的程序总是错漏百出的。二分的第一个程序出现在1942年,但是直到1962年出出现了第一个没有bug的二分程序,其编写正确难度可想而知。

 

解题技巧:

(1)整形数据题目:l 为下界,r 为上界

一般的整形数据的题其循环都是 :

while ( l < r )   然后l=mid+1,high=mid 这各形式的;

或者有的题目边界要求比较强就得是  

while ( l <= r) 然后 l=mid+1,r=mid-1 这各形式;

还有道题就是CF 371C那道中的边界处理要求比较高就是:

while(  l+1 < r ) 然后 l=mid,r=mid

(2)浮点型题目: #define eps 1e-5

大神说的话:“一般浮点型题目都会与精度打交道,所以势必与eps有关,因为如果如果精度要求0.01,那么如果你在 l=mid+eps这样做的话,这里我设eps为0.00001,那么时间复杂度就会乘以10^3了,那么既然二分是减少时间的,这样又会增加时间复杂 度,那该怎么避免这个problem呢。

所以在HDU 1551这题上我就掉进了这个坑了,我把精度写在 l=mid+eps里了,然后直接TLE。  我把精度写在while里面的时候时间直接下降很多。因为每次都是平分,这就与eps没多大关系了,只要能接近最优答案就行。所以技巧如下:

while( r - l >eps)  然后 l=mid , r=mid;即可。”。

解题的基本思路就是:

while( l < r )
{
  mid=(l+r)/2; //如果是整数用移位>>1更加快
  if(gao(mid)<=m) l=mid+1;  //gao函数是处理二分枚举之后验证最佳答案是否符合的函数
  else r=mid; 
}

下面是这些题的代码及分析:

 HDU1551    Cable master   http://acm.hdu.edu.cn/showproblem.php?pid=1551

算是我的二分第一题吧,题意是给你n根绳子,让你分成长度相等m段,求绳子的最长长度。以前根本不知道这种题可以用二分来做,感觉很神奇。

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <math.h>
#include <algorithm>
#define eps 1e-8
using namespace std;
int n,m;
double sum;
double a[10001];
bool judge(double s)
{
    int cnt=0;
    for(int i=0; i<n; i++)
    {
        cnt+=(int)(a[i]/s);//这根绳子可以分得段数
    }
    if(cnt>=m) return true;
    else return false;
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF&&(n||m))
    {
        sum=0;
        for(int i=0; i<n; i++)
        {
            scanf("%lf",&a[i]);
            sum+=a[i];
        }
        sum/=m;//绳子可以分的最大长度
        double l=0,r=sum;
        while(fabs(r-l)>eps)
        {
            double mid=(l+r)/2.0;
            if(judge(mid))
                l=mid;
            else r=mid;
        }
        printf("%.2lf\n",l);
    }
    return 0;
}

 。

二分题目总结(未完待续)

标签:style   blog   http   io   ar   color   os   sp   for   

原文地址:http://www.cnblogs.com/zhangmingcheng/p/4130682.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!