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

二分专题练习

时间:2019-02-16 15:33:39      阅读:189      评论:0      收藏:0      [点我收藏+]

标签:around   表示   clu   cow   保留   amp   order   class   lock   

整数集合上的二分

求均值的时候,不能/2,而是要>>1,这是因为/2向0取整,>>1向下取整,/2在二分值域包含负数的时候无法正常工作。

正确写出二分的流程是:

  1. 通过分析具体问题,确定左右半段哪一个是可行区间,以及mid归属哪一半段。
  2. 根据分析结果,选择r=mid,l=mid+1,mid=(l+r)>>1l=mid,r=mid-1,mid=(l+r+1)>>1的两个配套形式之一,保证每次的区间都能够缩小。
  3. 二分终止条件是l==r,该值就是答案所在位置。

实数域上的二分

确定精度eps,若保留k为小数则取eps=1e-(k+2)

分支选择r=midl=mid之一即可。

精度不易确定或表示时,采用固定循环次数的二分方法。

三分法求单峰函数极值

函数必须具有严格单调性,不然三分法不再适用。

POJ2018 Best Cow Fences

Farmer John‘s farm consists of a long row of N (1 <= N <= 100,000)fields. Each field contains a certain number of cows, 1 <= ncows <= 2000.

FJ wants to build a fence around a contiguous group of these fields in order to maximize the average number of cows per field within that block. The block must contain at least F (1 <= F <= N) fields, where F given as input.

Calculate the fence placement that maximizes the average, given the constraint.

0/1分数规划,二分答案判断即可,判断的方法是作差,判断有没有哪个区间和大于0,记录前缀和和前缀和最小值就行了。

时间复杂度\(O(N \log_2 ncows)\)

然而二分边界设成[1,2000]会WA,设成[-1e6,1e6]才能AC。我思忖这均值咋地得弄成负数了。

#include<iostream>
#include<cstdio>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;
    rg char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=data*10+ch-'0',ch=getchar();
    return data*w;
}
template<class T>il T read(rg T&x){
    return x=read<T>();
}
typedef long long ll;
co int MAXN=1e5+1;
double a[MAXN],b[MAXN],sum[MAXN];
int main(){
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    int N=read<int>(),L=read<int>();
    for(int i=1;i<=N;++i)
        read(a[i]);
    co double eps=1e-5;
    double l=-1e6,r=1e6;
    while(r-l>eps){
        double mid=(l+r)/2;
        for(int i=1;i<=N;++i)
            sum[i]=sum[i-1]+(b[i]=a[i]-mid);
        double ans=-1e10,min_val=1e10;
        for(int i=L;i<=N;++i){
            min_val=std::min(min_val,sum[i-L]);
            ans=std::max(ans,sum[i]-min_val);
        }
        if(ans>=0) l=mid;
        else r=mid;
    }
    printf("%d\n",int(r*1000));
    return 0;
}

二分专题练习

标签:around   表示   clu   cow   保留   amp   order   class   lock   

原文地址:https://www.cnblogs.com/autoint/p/10387700.html

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