菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
330
0

汇总____分治

原创
05/13 14:22
阅读数 50303

找出硬币

给你一个装有1 6枚硬币的袋子。1 6枚硬币中有一个是伪造的,并且那个伪造的硬币比真的硬币要轻一些。你的任务是找出这枚伪造的硬币。

 

金块问题

一袋金块中找最轻and最重的


n≤2,识别出最重和最轻的金块,一次比较就足够了。

n2,第一步,把这袋金块平分成两个小袋AB。第二步,分别找出在AB中最重和最轻的金块。设A中最重和最轻的金块分别为HA LA,以此类推,B中最重和最轻的金块分别为HB LB。第三步,通过比较HA HB,可以找到所有金块中最重的;通过比较LA LB,可以找到所有金块中最轻的。在第二步中,若n2,则递归地应用分而治之方法。

比较次数:c(n) = 2c(n/2 ) + 2


分治思想

分治(divide-and-conquer)就是分而治之的意思,其实质就是将原问题分成n个规模较小而结构与原问题相似的子问题;然后递归地解这些子问题,最后合并其结果就得到原问题的解。n=2时的分治法又称二分法

其三个步骤如下;

分解(Divide):将原问题分成一系列子问题。

解决(Conquer):递归地解各子问题。若子问题足够小,则可直接求解。

合并(combine);将子问题的结果合并成原问题的解。


由分治法所得到的子问题与原问题具有相同的类型。如果得到的子问题相对来说还太大,则可反复使用分治策略将这些子问题分成更小的同类型子问题,直至产生出不用进一步细分就可求解的子问题。

分治求解可用一个递归过程来表示。

要使分治算法效率高,关键在于如何分割?一般地,出于一种平衡原则,总是把大问题分成K个规模尽可能相等的子问题,但也有例外,如求表的最大最小元问题的算法,当n6时,等分定量成两个规模为3的子表L1L2不是最佳分割


分治策略的解题思路

if 问题不可分then begin

直接求解;

返回问题的解;

end

else begin

对原问题进行分治;

递归对每一个分治的部分求解

归并整个问题,得出全问题的解;

end;

一元三次方程求解

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

提示:记方程f(x)=ax3+bx2+cx+d,若存在2个数x1x2,且x1<x2f(x1)*f(x2)<0,则在(x1x2)之间一定有一个根。

样例

输入:1 -5 -4 20

输出:-2.00 2.00 5.00


A当已知区间(a,b)内有一个根时,用二分法求根,若区间(a,b)内有根,则必有f(a)·f(b)<0。重复执行如下的过程:

(1)a+0.0001>bf((a+b)/2)=0,则可确定根为(a+b)/2并退出过程;

(2)f(a)* f((a+b)/2)<0,则由题目给出的定理可知根在区间(a,(a+b)/2)中,故对区间重复该过程;

(3)f(a)* f((a+b)/2)>0 ,则必然有f((a+b)/2)* f(b)<0 ,根在((a+b)/2,b)中,对此区间重复该过程。

执行完毕,就可以得到精确到0.0001的根。

B求方程的所有三个实根

所有的根的范围都在-100100之间,且根与根之差的绝对值>=1。因此可知:在[-100,-99][-99,-98]……[99100][100100]201个区间内,每个区间内至多只能有一个根。即:除区间[100100]外,其余区间[a,a+1],只有当f(a)=0f(a)·f(a+1)<0时,方程在此区间内才有解。若f(a)=0 ,解即为a;若f(a)·f(a+1)<0 ,则可以利用A中所述的二分法迅速出找出解。

发表评论

0/200
330 点赞
0 评论
收藏
为你推荐 换一批