浅谈二分和二分答案

一般来讲我们会在以下情况用到二分:

  • 求单调函数的零点
  • 求一堆东西的最小值最大是多少
  • 很难直接算出答案,但是很好判定答案合不合法

如果想学就继续看吧!

二分查找

二分是一种可以再\(\mathcal{O}(\mathrm{ch}\log m)\)(\(m\)为数据规模,\(\mathrm{ch}\)为判断状态合法性check()函数时间复杂度)时间复杂度内求解问题的方法,主要是一个分治,每次将搜索范围减半。

我们以二分查找引入。

有一个有序序列,二分查找的思想如下:

1.定义L,R,mid代表答案在[L,R]内,中点为mid
2.查找mid所在值,如果mid大于查找值,搜索范围定为[L,mid],如果mid小于查找值,搜索范围定为[mid,R],如果查找到了,则返回L
3.将mid重新设为中点,并调至2

  • 二分查找的时间复杂度是\(\mathcal{O}(\log n)\)
  • 顺序查找的时间复杂度是\(\mathcal{O}(n)\)

现在比较它们两个:

例1:

例2:

代码的话在这:

//二分查找(递归)
int binarySearch(int list[],int left,int right,int number)
{
    if(list==NULL)  return -1;
    int index=0;
    int mid=(right+left)/2;
    if(left>right)
        return -1;
    if(number==list[mid])
    {
        index=mid;
        return index;
    }
    else if(number>list[mid]) binarySearch(list,mid+1,right,number);
    else binarySearch(list,left,mid-1,number);
}
//二分查找(循环)
int binarySearch(int list[],int left,int right,int number)
{
    if(list==NULL) return -1;
    while(left<right)
    {
        int mid=(right+left)/2;
        if (list[mid] == number) return mid;
        else if (number > list[mid]) left=mid+1;
        else if (number < list[mid]) right=mid-1;
    }
    return -1;
}

二分答案

二分答案嘛,就是想二分查找一样,只是判断改了,模板:

while(l<r)
{
    mid=(l+r)/2;
    if (check(mid)) r=mid;
    else l=mid+1;
}

check一般是贪心DP

具体应用

比如方程求根啦:

题目描述

有形如:\(ax^3+bx^2+cx^1+dx^0=0\) 这样的一个一元三次方程。给出该方程中各项的系数(a,b,c,d均为实数),并约定该方程存在三个不同实根(根的范围在\(-100\)至\(100\)之间),且根与根之差的绝对值\(≥1\)。要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后\(2\)位。

提示:记方程\(f(x)=0\),若存在两个数\(x_1\)和\(x_2\),且\(x_1<x_2\),\(f(x_1)\times f(x_2)<0\),则在\((x_1,x_2)\)之间一定有一个根。

输入格式

一行,\(4\)个实数\(A,B,C,D\)。

输出格式

一行,\(3\)个实根,并精确到小数点后\(2\)位。

输入输出样例

输入

1 -5 -4 20

输出

-2.00 2.00 5.00

这提示明摆着疯狂暗示我们二分啊,按提示二分即可:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define db double
using namespace std;
db a,b,c,d,f1,f2;
int cnt=0;
db check(db x){return a*x*x*x+b*x*x+c*x+d;}
int main()
{
    cin>>a>>b>>c>>d;
    db l,r,mid;
    for(db i=-100;i<=100;++i)
    {
        f1=check(i);
        f2=check(i+1);
        if(!f1){printf("%.2lf ",i);cnt++;}
        if(f1*f2<0)
        {
            l=i,r=i+1;
            while(r-l>=0.001)
            {
                mid=(l+r)/2;
                if (check(mid)*check(r)>0) r=mid;
                else l=mid;
            }
            printf("%.2lf ",r);
            cnt++;
        }
        if (cnt==3) break;
    }
    return 0;
}

小学奥数啦:

题目描述

甲、乙两人同时从A地出发要尽快同时赶到B地。出发时A地有一辆小车,可是这辆小车除了驾驶员外只能带一人。已知甲、乙两人的步行速度一样,且小于车的速度。问:怎样利用小车才能使两人尽快同时到达。

输入格式

仅一行,三个数据分别表示AB两地的距离s,人的步行速度a,车的速度b。

输出格式

两人同时到达B地需要的最短时间,保留6位小数。

输入输出样例

输入

120 5 25

输出

9.600000

这种题想不出来也可以二分啊。

思路如下

然后二分C点啦:

#include<cstdio>
#include<cmath>
int main()
{
    double s,s1,s2,v1,v2,t1,t2,p;
    double a,b;
    scanf("%lf%lf%lf",&s,&v1,&v2);
    s1=0;
    s2=s;
    do
    {
        p=(s1+s2)/2.0;
        a=p/v2;
        b=(p-a*v1)/(v1+v2);
        t1=a+(s-p)/v1;
        t2=a+b+(s-(a+b)*v1)/v2;
        if(t1<t2)
            s2=p;
        else
            s1=p;
    }
    while (fabs(t1-t2)>1e-8);
    printf("%.6lf",t1);
    return 0;
}

原文地址:https://www.cnblogs.com/CDOI-24374/p/12274830.html

时间: 2024-08-29 07:52:51

浅谈二分和二分答案的相关文章

整体二分浅谈

整体二分浅谈 一.前置知识 在学习整体二分之前,要学会二分,以及二分的分治思想. 二.整体二分浅谈及例题 例题:bzoj2527: [Poi2011]Meteors 对于这道题是整体二分的经典例题,我们先抛开整体二分,思考二分怎么做.对于一个询问,因为答案有单调性,如果$x$时刻为最小可以时刻,则比$x$小的时刻都不可以,比$x$大的时刻都可以,所以我们可以进行二分答案,并加以验证.先不说怎样验证,就单是时间复杂度就不能接受,$O(nmlog_2^n)$. 如果一个一个进行二分时间复杂度不允许,

浅谈自然语言处理基础(下)

命名实体识别 命名实体的提出源自信息抽取问题,即从报章等非结构化文本中抽取关于公司活动和国防相关活动的结构化信息,而人名.地名.组织机构名.时间和数字表达式结构化信息的关键内容,所以需要从文本中去识别这些实体指称及其类别,即命名实体识别和分类. 21世纪以后,基于大规模语料库的统计方法成为自然语言处理的主流,以下是基于统计模型的命名实体识别方法归纳: 基于CRF的命名实体识别方法 基于CRF的命名实体识别方法简便易行,而且可以获得较好的性能,广泛地应用于人名.地名和组织机构等各种类型命名实体的识

浅谈MySQL索引背后的数据结构及算法

摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持 也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等.为了避免混乱,本文将只关注于BTree索引,因为这是 平常使用MySQL时主要打交道的索引,至于哈希索引和全文索引本文暂不讨论. 文章主要内容分为四个部分. 第一部分主要从数据结构及算法理论层面讨论MySQL数据库索引的数理基础. 第二部分结合MySQL数据库中

【算法微解读】浅谈01分数规划

浅谈01分数规划 所谓01分数规划,看到这个名字,可能会想到01背包,其实长得差不多. 这个算法就是要求"性价比"最高的解.sum(v)/sum(w)最高的解. 定义 我们给定两个数组,a[i]表示选取i的收益,b[i]表示选取i的代价.如果选取i,定义x[i]=1否则x[i]=0.每个物品只有选和不选的两种方案,求一个选择的方案使得R=sigma(a[i]x[i])/sigma(b[i]x[i]),也就是选择物品的总收益/总代价最大或者最小. 01分数规划问题主要包含以下几个问题:

从《楼房重建》出发浅谈一类使用线段树维护前缀最大值的算法

首先需要申明的是,真的是浅谈,因为我对这个算法的认识还是非常低的. 既然是从<楼房重建>出发,那么当然是先看看这道题: [清华集训2013]楼房重建 bzoj 链接 题意简述: 有 \(n\) 栋楼,第 \(i\) 栋的高度为 \(H_i\),也就是说第 \(i\) 栋楼可以抽象成一条两端点为 \((i, 0)\) 和 \((i, H_i)\) 的线段. 初始时 \(H_i\) 均为 \(0\),要支持动态修改单点的 \(H_i\). 每次询问从 \(O(0, 0)\) 点可以看到多少栋楼房.

图标字体化浅谈[转]

在做手机端Web App项目中,经常会遇到小图标在手机上显示比较模糊的问题,经过实践发现了一种比较好的解决方案,图标字体化.在微社区项目中,有很多小的Icon(图标),如分享.回复.赞.返回.话题.访问.箭头等,这些Icon(图标)一般都是纯色的.开始制作时考虑用双倍大小的Sprite图,通过CSS样式设置只显示二分之一尺寸,这样在Retina屏上显示的大小是正常的,一旦放大屏幕后图标又变得模糊不清,测试的效果不是很理想,后来又考虑多套图标适配方案.SVG矢量图等,都因为种种原因放弃掉了(如多套

浅谈算法和数据结构

: 一 栈和队列 http://www.cnblogs.com/yangecnu/p/Introduction-Stack-and-Queue.html 最近晚上在家里看Algorithems,4th Edition,我买的英文版,觉得这本书写的比较浅显易懂,而且“图码并茂”,趁着这次机会打算好好学习做做笔记,这样也会印象深刻,这也是写这一系列文章的原因.另外普林斯顿大学在Coursera 上也有这本书同步的公开课,还有另外一门算法分析课,这门课程的作者也是这本书的作者,两门课都挺不错的. 计算

浅谈算法和数据结构: 十 平衡查找树之B树

转载自 http://www.cnblogs.com/yangecnu/p/3632027.html 浅谈算法和数据结构: 十 平衡查找树之B树 前面讲解了平衡查找树中的2-3树以及其实现红黑树.2-3树种,一个节点最多有2个key,而红黑树则使用染色的方式来标识这两个key. 维基百科对B树的定义为“在计算机科学中,B树(B-tree)是一种树状数据结构,它能够存储数据.对其进行排序并允许以O(log n)的时间复杂度运行进行查找.顺序读取.插入和删除的数据结构.B树,概括来说是一个节点可以拥

浅谈java类集框架和数据结构(2)

继续上一篇浅谈java类集框架和数据结构(1)的内容 上一篇博文简介了java类集框架几大常见集合框架,这一篇博文主要分析一些接口特性以及性能优化. 一:List接口 List是最常见的数据结构了,主要有最重要的三种实现:ArrayList,Vector,LinkedList,三种List均来自AbstracList的实现,而AbstracList直接实现了List接口,并拓展自AbstractCollection. 在三种实现中,ArrayList和Vector使用了数组实现,可以认为这两个是