二分查找的应用 ——李江贝, 郝琰 2017年9月28日.

Slides:



Advertisements
Similar presentations
2014 年浙江省数量资料 华图网校 刘有珍 数字推理 年份题量数字规律 三级等差 2. 和递推 3. 幂次修正 4. 倍数递推 5. 倍数递推 6. 特殊差级 7. 倍数递推 8. 倍数递推 9. 积递推 10. 分数数列
Advertisements

1 第 3 章 C++ 中的条件与循环 第 3 次见面! acm.nefu.edu.cn/C++_03.ppt.
While 迴圈 - 不知重複執行次數
首页 全国高等学校招生考试统一考试 监考员培训 广州市招生考试委员会办公室.
精彩人生.
延边大学 2016年度本科专业评估指标体系解读.
XX啤酒营销及广告策略.
2011年会计初级职称全国统考 初级会计实务 教案 主讲:高峰 2010年12月.
人口增长.
第四章:长期股权投资 长期股权投资效果 1、控制:50%以上 有权决定对方财务和经营.
報告書名:父母會傷人 班級:二技幼四甲 姓名:吳婉如 學號:1A2I0034 指導老師:高家斌
第一章 会计法律制度 补充要点.
二、个性教育.
Introduction 基本概念 授課老師:蕭志明
媽,我們真的不一樣 青少年期與中年期 老師: 趙品淳老師 組員: 胡珮玟4A1I0006 馬菀謙4A1I0040
簡報大綱 前言 為何會有異質採購最低標 異質採購最低標法令規定 各種決標方式之履約成果分析.
氣喘 組別:第一組 組員: 4A 蔡易儒 4A1I0026 鄭筠蒨 4A1I0034 韓宜瑄 4A1I0035 劉毓眉
“八皇后”问题 崔萌萌 吕金华.
主讲:计算机工程学院 李兰 答疑地点:主教学楼B区213
新准则框架与首次执行 企业会计准则 主讲人:陈清宇.
程序设计实习 3月份练习解答
碘缺乏病.
实现人生的华丽转身 —2014年高速公路考试备考指导 中公教育陈修晓.
第五章 经纪业务相关实务.
班級:二幼三甲 姓名:郭小瑄 、 詹淑評 學號:1A2I0029 、1A2I0025
初中语文总复习 说明文 阅读专题 西安市第六十七中学 潘敏.
指導老師:陳韻如 姓名:吳宜珊 學號:4A0I0911 班級:幼保二乙
财经法规与会计职业道德 (3) 四川财经职业学院.
优卡会介绍资料 ——健 康 数 据 管 理 专 家—— ——爱上优卡会,生活好品味
<<广东省中小学生体能素质评价标准>>
命题与四种命题 高二数学 选修2-1 第一章 常用逻辑用语.
1.1.2 四 种 命 题.
傳統童玩遊戲創新 組別:第八組 班級:幼保二甲 組員: 4A0I0005柯舒涵 4A0I0011謝孟真
面向海洋的开放地区——珠江三角洲 山东省高青县实验中学:郑宝田.
第四课时 常见天气系统 阜宁一中 姚亚林.
成才之路 · 地理 人教版 · 必修3 路漫漫其修远兮 吾将上下而求索.
第五章 定积分及其应用.
第8章 查找 数据结构(C++描述).
班級:觀光一B 姓名:李詩涵 座號: 18 指導老師:杜光玉
存货的核算 一、项目任务 1、原材料核算 ——按实际成本核算 ——按计划成本核算 2、低值易耗品及包装物核算 3、存货清查的核算
北师大版七年级数学 5.5 应用一元一次方程 ——“希望工程”义演 枣庄市第三十四中学 曹馨.
欢迎来到我们的课堂!.
专题研讨课二: 数组在解决复杂问题中的作用
海洋存亡 匹夫有责 ——让我们都来做环保小卫士 XX小学三(3)班.
第二章 负债 1、负债的概念:是指过去的交易或事项形成的、预 期会导致经济利益流出企业的现时义务。 2、负债的分类 流动负债 短期借款
Chapter 7 Search.
第四章第一节 增值税法律制度2 主讲老师:梁天 经济法基础.
狂賀!妝品系同學美容乙級通過 妝品系三甲 學號 姓名 AB 陳柔諺 AB 陳思妤 AB 張蔡婷安
东北林业大学 陈宇 ACM程序设计 东北林业大学 陈宇
计算机网络讲义 第5章 批量数据处理—数组 一维数组 排序和查找 二维数组 字符串.
第九章 查找 2018/12/9.
数据结构 -Maple Related- 牟克典 数学科学学院信息科学系 2012秋季 1/16/2019.
初级职称前导课 第一章 资产 主讲老师:海伦老师(兰老师).
第九章 查找 2019/2/16.
計數式重複敘述 for 迴圈 P
东北林业大学 陈宇 ACM程序设计 东北林业大学 陈宇
性騷擾之調查與防治 主講人:龜山分局 家防官 劉淑卿.
4 條件選擇 4.1 程式基本結構 循序式結構 選擇式結構 重複式結構 4-3
今天, AC 你 了吗? 2019/4/26.
第七章  事业单位支出的核算      §第一节  支出概述     §第二节  拨出款项     §第三节  各项支出     §第四节  成本费用.
動態規劃 Dynamic Programming (DP)
演算法時間複雜度 (The Complexity of Algorithms)
课前注意 课前注意 大家好!欢迎加入0118班! 请注意以下几点: 1.服务:卡顿、听不清声音、看不见ppt—管家( ) 2.课堂秩序:公共课堂,勿谈与课堂无关或消极的话题。 3.答疑:上课听讲,课后答疑,微信留言。 4.联系方式:提示老师手机/微信: QQ:
算法导论第一次习题课.
复杂度和测试数据 吴章昊.
第3章  函数与方程  第2课时 用二分法求方程的近似解.
坚持,努力,机会留给有准备的人 第一章 四大金融资产总结 主讲老师:陈嫣.
平面的基本性质 江苏省泰州中学 数学组 姜莹. 平面的基本性质 江苏省泰州中学 数学组 姜莹.
Advanced Competitive Programming
异常交易监管等监察业务培训 大连商品交易所 监察部 2018年4月.
Presentation transcript:

二分查找的应用 ——李江贝, 郝琰 2017年9月28日

高中学过的二分法

查找图解

二分法基本思想: 适用范围: 1.题目答案满足某种意义上的单调 性 2.直接求解难以接受 3.验证解是否可行较为容易

二分法基本思想: 常见的模型 1.求xx的最值 2.求最少/多需要多少xx才能满足 xx”

常见的模型 1.求xx的最值 2.求最少/多需要多少xx才能满足xx” 3.xx最大值尽可能小,xx最小值尽可能大 时间复杂度 log 二分法基本思想: 常见的模型 1.求xx的最值 2.求最少/多需要多少xx才能满足xx” 3.xx最大值尽可能小,xx最小值尽可能大 时间复杂度 log

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

算法思路: 1.取一定包含根的某一区间(a,b),其中 f(a)*f(b)<0 2.取(a,b)的中点c.若f(a)*f(c)<0,则将求解区 间调整为(a,c);否则,求解区间为(c,b) 3.对新的求解区间重复1,2两操作,直到求解 区间满足题目所要求的的精度为止

参考代码: double caculate(double l,double r){ double m; while(r-l >= 0.001){ //误差范围内 m = (l+r)/2; double mid = f(m),fl = f(l),fr = f(r); if(mid * fl > 0)l = m; //(l,m)中有零点 else if(mid * fr > 0)r = m; //(m,r)中有零点 if(mid == 0)return m; } return m; //当没找到确切的零点时,返回近似值

还想了些什么 三次方程求根公式? 通过求导得到三次函数的两个最值点,然后对三个区间进行二分。

OJ 1580 奔跑吧保祥 Description 保祥最近开始使用一款APP进行跑步。 APP中预设了不同的跑步 路径供保祥选择,每一种路径中会自动生成不同的感应位点。 保祥是个不喜欢拐弯抹角的人,因此他选择沿着笔直的宣怀大道 跑步,APP为他规定了跑步的起点和终点。在起点和终点之间,有 N 个位点(不含起点和终点)。跑步时,保祥必须按次序经过每一 个位点,最终到达终点。 为了减少中途找点的次数,提高跑步质量,APP设计者计划删除 一些位点,使得路径中相邻两个位点间的最短距离尽可能长。设 计者计划至多从起点和终点之间删除 M 个位点(不能删除起点 和终点)。求最短距离的最大值。

去掉若干个点 求最短距离的最大值

算法思路 “最短距离的最大值”,直接求解不方便,但要验证某一值x是否可能 是最短距离比较容易。譬如对于给定的距离值x,只需验证,删除M 个位点后,能否满足各位点间距离均大于等于x即可。因此题目可 转化为求得满足该条件的最大的x。(由于可验证比这个值更大的 距离都不可能是最短距离,而这个距离有可能是最短距离,因此该 值一定是最短距离的最大值)

算法思路 “最短距离的最大值”,直接求解不方便,但要验证某一值x是否可能 是最短距离比较容易。譬如对于给定的距离值x,只需验证,删除M 个位点后,能否满足各位点间距离均大于等于x即可。因此题目可 转化为求得满足该条件的最大的x。(由于可验证比这个值更大的 距离都不可能是最短距离,而这个距离有可能是最短距离,因此该 值一定是最短距离的最大值) 从最短距离的最大值x下手。若x=0,各位点间间距一定都大于等于 x(注意,这里的最短距离不一定是真实可达到的最短距离,但它 一定小于等于可达到的最短距离。我们会在计算中逐渐取到可达到 的最短距离的最大值。)因此设low=0,high=L。

算法思路 “最短距离的最大值”,直接求解不方便,但要验证某一值x是否可能 是最短距离比较容易。譬如对于给定的距离值x,只需验证,删除M 个位点后,能否满足各位点间距离均大于等于x即可。因此题目可 转化为求得满足该条件的最大的x。(由于可验证比这个值更大的 距离都不可能是最短距离,而这个距离有可能是最短距离,因此该 值一定是最短距离的最大值) 从最短距离的最大值x下手。若x=0,各位点间间距一定都大于等于 x(注意,这里的最短距离不一定是真实可达到的最短距离,但它 一定小于等于可达到的最短距离。我们会在计算中逐渐取到可达到 的最短距离的最大值。)因此设low=0,high=L。 二分区间,令mid=(low+high)/2。讨论,从N个位点中删除M个能 否满足剩余所有位点的间距不比mid 小。若满足,讨论(mid, high),否则,讨论(low,mid)

算法思路 注:判断x是否合乎题意的方法:设初始位点的分布存在数组 a[maxn]中。首先,从离起点距离s=0开始,若a[0]<s+x,说明0 到a[0]之间的距离小于这个最短距离,需要把a[0]位点去除,去 除的位点数加一。之后再看0到a[1],如果还是小于x,去除的 位点数加一,直到找到某一位点离起点距离大于x,把该位点置 为起点,重复上述过程;若a[0]>=s+x,直接把第一个位点置为 起点。以此类推。

参考代码 high = L; low = 0; while (high - low > 1) { mid = (high + low) / 2; if (valid(mid, N, M)) low = mid; else high = mid; } if (valid(high, N, M)) cout << high; else cout << low; bool valid(int x, int N, int M) { int start, num=0,j; start = 0; for (j = 0; j <= N - 1; j++) { if (a[j] < start + x) num += 1; else start = a[j]; } return num <= M;

OJ 1581 LIS (longest increasing subsequence) Description 给一个序列,求它的最长递增子序列的长度。 如 1 6 2 5 4 7 这些数字中,1 2 5(4) 7 是最长的上升子序列,长度为4. Input Format 第一行有三个整数n ,代表序列的长度。 接下来一行 n 个正整数代表序列x[1], x[2]……, x[n]。 Output Format 输出最长递增子序列的长度。 注意:答案没有对任何数取模。

一个共识 如果一个序列为1, 3, 5, 9, 6, 8 我们先只考虑前5个元素,(1,3,5,9,6) 可以构 成两个最长递增子序列(1,3,5,9)和(1,3,5, 6) 这时我们考虑元素8,他更喜欢(1,3,5,6)这个序 列,而讨厌(1,3,5,9)这个序列,因为它可以与 1,3,5,6构成长度为5的序列

我们怎么办呢 开一个数组d[] d[i] 存储 长度为i的最长递增子序列 的 最小末尾

算法思路 以序列{6,7,8,9,10,1,2,3,4,5,6}来说明

算法思路 以序列{6,7,8,9,10,1,2,3,4,5,6}来说明 程序开始时,最长递增序列长度为1(每个元素都是一个长 度为1的递增序列),当处理第2个元素时发现7比最长递增 序列6的最大元素还要大,所以将6,7结合生成长度为2的递 增序列,说明已经发现了长度为2的递增序列,依次处理, 到第5个元素(10),这一过程中B数组的变化过程是

算法思路 以序列{6,7,8,9,10,1,2,3,4,5,6}来说明 程序开始时,最长递增序列长度为1(每个元素都是一个长 度为1的递增序列),当处理第2个元素时发现7比最长递增 序列6的最大元素还要大,所以将6,7结合生成长度为2的递 增序列,说明已经发现了长度为2的递增序列,依次处理, 到第5个元素(10),这一过程中B数组的变化过程是 6

算法思路 以序列{6,7,8,9,10,1,2,3,4,5,6}来说明 程序开始时,最长递增序列长度为1(每个元素都是一个长 度为1的递增序列),当处理第2个元素时发现7比最长递增 序列6的最大元素还要大,所以将6,7结合生成长度为2的递 增序列,说明已经发现了长度为2的递增序列,依次处理, 到第5个元素(10),这一过程中B数组的变化过程是 6  6,7

算法思路 以序列{6,7,8,9,10,1,2,3,4,5,6}来说明 程序开始时,最长递增序列长度为1(每个元素都是一个长 度为1的递增序列),当处理第2个元素时发现7比最长递增 序列6的最大元素还要大,所以将6,7结合生成长度为2的递 增序列,说明已经发现了长度为2的递增序列,依次处理, 到第5个元素(10),这一过程中B数组的变化过程是 6  6,7  6,7,8

算法思路 以序列{6,7,8,9,10,1,2,3,4,5,6}来说明 程序开始时,最长递增序列长度为1(每个元素都是一个长 度为1的递增序列),当处理第2个元素时发现7比最长递增 序列6的最大元素还要大,所以将6,7结合生成长度为2的递 增序列,说明已经发现了长度为2的递增序列,依次处理, 到第5个元素(10),这一过程中B数组的变化过程是 6  6,7  6,7,8  6,7,8,9

算法思路 以序列{6,7,8,9,10,1,2,3,4,5,6}来说明 程序开始时,最长递增序列长度为1(每个元素都是一个长 度为1的递增序列),当处理第2个元素时发现7比最长递增 序列6的最大元素还要大,所以将6,7结合生成长度为2的递 增序列,说明已经发现了长度为2的递增序列,依次处理, 到第5个元素(10),这一过程中B数组的变化过程是 6  6,7  6,7,8  6,7,8,9 6,7,8,9,10

算法思路 以序列{6,7,8,9,10,1,2,3,4,5,6}来说明   之前处理到过的序列: 6,7,8,9,10

算法思路 以序列{6,7,8,9,10,1,2,3,4,5,6}来说明 之前处理到过的序列: 6,7,8,9,10   之前处理到过的序列: 6,7,8,9,10 开始处理第6个元素是1,查找比1大的最小元素,发现是长度为1的子序列的最大元素6, 说明1是最大元素更小的长度为1的递增序列,用1替换6,形成新数组1,7,8,9,10。 然后查找比第7个元素(2)大的最小元素,发现7,说明存在长度为2的序列,其末元素2, 比7更小,用2替换7,依次执行,直到所有元素处理完毕,生成新的数组1,2,3,4, 5,最后将6加入B数组,形成长度为6的最长递增子序列.

算法思路 以序列{6,7,8,9,10,1,2,3,4,5,6}来说明 之前处理到过的序列: 6,7,8,9,10   之前处理到过的序列: 6,7,8,9,10 开始处理第6个元素是1,查找比1大的最小元素,发现是长度为1的子序列的最大元素6, 说明1是最大元素更小的长度为1的递增序列,用1替换6,形成新数组1,7,8,9,10。 然后查找比第7个元素(2)大的最小元素,发现7,说明存在长度为2的序列,其末元素2, 比7更小,用2替换7,依次执行,直到所有元素处理完毕,生成新的数组1,2,3,4, 5,最后将6加入B数组,形成长度为6的最长递增子序列. 1,7,8,9,10

算法思路 以序列{6,7,8,9,10,1,2,3,4,5,6}来说明 之前处理到过的序列: 6,7,8,9,10   之前处理到过的序列: 6,7,8,9,10 开始处理第6个元素是1,查找比1大的最小元素,发现是长度为1的子序列的最大元素6, 说明1是最大元素更小的长度为1的递增序列,用1替换6,形成新数组1,7,8,9,10。 然后查找比第7个元素(2)大的最小元素,发现7,说明存在长度为2的序列,其末元素2, 比7更小,用2替换7,依次执行,直到所有元素处理完毕,生成新的数组1,2,3,4, 5,最后将6加入B数组,形成长度为6的最长递增子序列. 1,7,8,9,10  1,2,8,9,10

算法思路 以序列{6,7,8,9,10,1,2,3,4,5,6}来说明 之前处理到过的序列: 6,7,8,9,10   之前处理到过的序列: 6,7,8,9,10 开始处理第6个元素是1,查找比1大的最小元素,发现是长度为1的子序列的最大元素6, 说明1是最大元素更小的长度为1的递增序列,用1替换6,形成新数组1,7,8,9,10。 然后查找比第7个元素(2)大的最小元素,发现7,说明存在长度为2的序列,其末元素2, 比7更小,用2替换7,依次执行,直到所有元素处理完毕,生成新的数组1,2,3,4, 5,最后将6加入B数组,形成长度为6的最长递增子序列. 1,7,8,9,10  1,2,8,9,10 1,2,3,9,10

算法思路 以序列{6,7,8,9,10,1,2,3,4,5,6}来说明 之前处理到过的序列: 6,7,8,9,10   之前处理到过的序列: 6,7,8,9,10 开始处理第6个元素是1,查找比1大的最小元素,发现是长度为1的子序列的最大元素6, 说明1是最大元素更小的长度为1的递增序列,用1替换6,形成新数组1,7,8,9,10。 然后查找比第7个元素(2)大的最小元素,发现7,说明存在长度为2的序列,其末元素2, 比7更小,用2替换7,依次执行,直到所有元素处理完毕,生成新的数组1,2,3,4, 5,最后将6加入B数组,形成长度为6的最长递增子序列. 1,7,8,9,10  1,2,8,9,10 1,2,3,9,10 1,2,3,4,10

算法思路 以序列{6,7,8,9,10,1,2,3,4,5,6}来说明 之前处理到过的序列: 6,7,8,9,10   之前处理到过的序列: 6,7,8,9,10 开始处理第6个元素是1,查找比1大的最小元素,发现是长度为1的子序列的最大元素6, 说明1是最大元素更小的长度为1的递增序列,用1替换6,形成新数组1,7,8,9,10。 然后查找比第7个元素(2)大的最小元素,发现7,说明存在长度为2的序列,其末元素2, 比7更小,用2替换7,依次执行,直到所有元素处理完毕,生成新的数组1,2,3,4, 5,最后将6加入B数组,形成长度为6的最长递增子序列. 1,7,8,9,10  1,2,8,9,10 1,2,3,9,10 1,2,3,4,10  1,2,3,4,5

算法思路 以序列{6,7,8,9,10,1,2,3,4,5,6}来说明 之前处理到过的序列: 6,7,8,9,10   之前处理到过的序列: 6,7,8,9,10 开始处理第6个元素是1,查找比1大的最小元素,发现是长度为1的子序列的最大元素6, 说明1是最大元素更小的长度为1的递增序列,用1替换6,形成新数组1,7,8,9,10。 然后查找比第7个元素(2)大的最小元素,发现7,说明存在长度为2的序列,其末元素2, 比7更小,用2替换7,依次执行,直到所有元素处理完毕,生成新的数组1,2,3,4, 5,最后将6加入B数组,形成长度为6的最长递增子序列. 1,7,8,9,10  1,2,8,9,10 1,2,3,9,10 1,2,3,4,10  1,2,3,4,5  1,2,3,4,5,6

算法思路 而在上述过程中,为了查找到合适的放置元素的位置,我们 需要用到二分查找 二分查找的结果,我们的目的是找到这样的一个j,使满足 A[B[j]] > A[i]的所有j中,j取得最小值

算法思路 而在上述过程中,为了查找到合适的放置元素的位置,我们 需要用到二分查找 二分查找的结果,我们的目的是找到这样的一个j,使满足 A[B[j]] > A[i]的所有j中,j取得最小值 比如把4放入1,2,3,9,10

算法思路 而在上述过程中,为了查找到合适的放置元素的位置,我们 需要用到二分查找 二分查找的结果,我们的目的是找到这样的一个j,使满足 A[B[j]] > A[i]的所有j中,j取得最小值 比如把4放入1,2,3,9,10 (0+4)/2=2,先和3比,4比3大,查找区间变为 9,10

算法思路 而在上述过程中,为了查找到合适的放置元素的位置,我们 需要用到二分查找 二分查找的结果,我们的目的是找到这样的一个j,使满足 A[B[j]] > A[i]的所有j中,j取得最小值 比如把4放入1,2,3,9,10 (0+4)/2=2,先和3比,4比3大,查找区间变为 9,10 (0+1)/2=0,再和9比,4比9小,将9替换为4

算法思路 而在上述过程中,为了查找到合适的放置元素的位置,我们 需要用到二分查找 二分查找的结果,我们的目的是找到这样的一个j,使满足 A[B[j]] > A[i]的所有j中,j取得最小值 比如把4放入1,2,3,9,10 (0+4)/2=2,先和3比,4比3大,查找区间变为 9,10 (0+1)/2=0,再和9比,4比9小,将9替换为4 序列变为1,2,3,4,10

参考代码 int HALF(int x[], int low, int high, int num) { int LIS(int * x,int sum) { int k, current = 0, tmp; answer[0] = x[0]; for (k = 1;k < sum;++k) { if (x[k] > answer[current]) answer[++current] = x[k]; else { tmp = HALF(answer, 0, current, x[k]); if (answer[tmp] < x[k]) tmp++; answer[tmp] = x[k]; } return (current + 1); int HALF(int x[], int low, int high, int num) { if (low >= high) { return low; } int mid = (low + high) / 2; if (num < x[mid]) { return HALF(x, low, mid - 1, num);} else return HALF(x, mid + 1, high, num); }

Q&A THANKES