基本的算法策略
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C:0——9 六位数表示为A*10000+B*1000+C*100+A*10+B,
共尝试800次。
2)约束条件为:
每次尝试,先求5位数与A的积,再测试积的各位是否相
同,若相同则找到了问题的解。
测试积的各位是否相同比较简单的方法是,从低位开始,
每次都取数据的个位,然后整除10,使高位的数字不断变
成个位,并逐一比较。
• 应用
蛮力策略的应用很广,具体表现形式各异,数据结构课程中学 习的:选择排序、冒泡排序、插入排序、顺序查找、朴素的字符 串匹配等,都是蛮力策略具体应用。
4.2.1 枚举法
枚举( enumerate)法(穷举法)是蛮力策略的一种表现形式, 也是一种使用非常普遍的思维方法。它是根据问题中的条件将可能 的情况一一列举出来,逐一尝试从中找出满足问题条件的解。但有 时一一列举出的情况数目很大,如果超过了我们所能忍受的范围, 则需要进一步考虑,排除一些明显不合理的情况,尽可能减少问题 可能解的列举数目。
多数问题需要所有子问题的解,并由子问题的解,使用恰 当的方法合并成为整个问题的解,比如合并排序,就是不断将 子问题中已排好序的解合并成较大规模的有序子集。
wenku.baidu.com
2.适合用分治法策略的问题 当求解一个输入规模为n且取值又相当大的问题时,用蛮力策略 效率一般得不到保证。若问题能满足以下几个条件,就能用分治法 来提高解决问题的效率。 1) 能将这n个数据分解成k个不同子集合,且得到k个子集合是 可以独立求解的子问题,其中1<k≤n; 2) 分解所得到的子问题与原问题具有相似的结构,便于利用递 归或循环机制; 在求出这些子问题的解之后,就可以推解出原问题的解;
分治法的基本步骤在每一层递归上都有三个步骤:
1)分解:将原问题分解为若干个规模较小,相互独立,与原 问题形式相同的子问题;
2)解决:若子问题规模较小而容易被解决则直接解,否则再 继续分解为更小的子问题,直到容易解决;
3)合并:将已求解的各个子问题的解,逐步合并为原问题的 解。
说明:
有时问题分解后,不必求解所有的子问题,也就不必作第三 步的操作。比如折半查找,在判别出问题的解在某一个子问题 中后,其它的子问题就不必求解了,问题的解就是最后(最小) 的子问题的解。分治法的这类应用,又称为“减治法”。
分治法的一般的算法设计模式如下:
Divide-and-Conquer(int n)
第四章 基本的算法策略
4.1 迭代算法
• 概念 用变量的旧值递推出新值的解决问题的方法
• 适合的范围 数值计算
• 类型 (1)递推法
sn=sn-1+An (2)倒推法
4.1.1 递推法
【例1】兔子繁殖问题
问题描述:一对兔子从出生后第三个月开始,每月生 一对小兔子。小兔子到第三个月又开始生下一代小 兔子。假若兔子只生不死,一月份抱来一对刚出生 的小兔子,问一年中每个月各有多少只兔子。
算法1如下: main( ) { int A,B,C,D,E,E1,F,G1,G2,i; for(A=3; A<=9; A++)
for(B=0; B<=9; B++) for(C=0; C<=9; C++)
{ F=A*10000+B*1000+C*100+A*10+B; E=F*A; E1=E; G1=E1 mod 10; for(i=1; i<=5; i++) { G2=G1; E1=E1/10; G1= E1 mod 10;
问题分析:则繁殖过程如下:
一月 二月 三月 四月 五月 六月 ……
1 1 1+1=2 2+1=3 3+2=5 5+3=8 …… 数 学 建 模 : y1=y2=1 , yn=yn-1+yn-2 , n=3 , 4 ,
5,……。
算法1:
main( ) { int i,a=1,b=1;
print(a,b); for(i=1;i<=10;i++)
if(G1<>G2 ) break; } if(i=6) print( F,”*”,A,”=”,E); } }
4.3 分而治之算法
4.3.1 分治算法框架
1.算法设计思想
分治法求解问题的过程是,将整个问题分解成若干个小问题后分 而治之。如果分解得到的子问题相对来说还太大,则可反复使用 分治策略将这些子问题分成更小的同类型子问题,直至产生出方 便求解的子问题,必要时逐步合并这些子问题的解,从而得到问 题的解。
4.3.2 二分法
不同于现实中对问题(或工作)的分解,可能会考虑问题 (或工作)的重点、难点、承担人员的能力等来进行问题的分 解和分配。在算法设计中每次一个问题分解成的子问题个数一 般是固定的,每个子问题的规模也是平均分配的。当每次都将 问题分解为原问题规模的一半时,称为二分法。二分法是分治 法较常用的分解策略,数据结构课程中的折半查找、归并排序 等算法都是采用此策略实现的。
{ c=a+b; print (c); a=b; b=c;
} }
4.1.2 倒推法
所谓倒推法:是对某些特殊问题所采用的违反通常习惯的, 从 后向前推解问题的方法。
【例】猴子吃桃问题 一只小猴子摘了若干桃子,每天吃现有桃的一半多一个, 到第10天时就只有一个桃子了,求原有多少个桃? 数学模型:每天的桃子数为:a10=1, a9=(1+a10)*2, a8=(1+a9) *2,……a10=1, 递推公式为:ai=(1+ai+1)*2 I = 9,8,7,6……1 算法如下 :
main( ) { int i,s; s=1; for (i=9 ;i>=1;i=i-1) s=(s+1)*2 print (s);
}
4.2 蛮力法
• 蛮力法是基于计算机运算速度快这一特性,在解决问题时采 取的一种“懒惰”的策略。这种策略不经过(或者说是经过很少的) 思考,把问题的所有情况或所有过程交给计算机去一一尝试,从 中找出问题的解。
用枚举法解决问题,通常可以从两个方面进行算法设计:
1)找出枚举范围:分析问题所涉及的各种情况。
2)找出约束条件:分析问题的解需要满足的条件,并用逻辑 表达式表示。
【例】解数字迷:
ABCAB
×
A
DDDDDD
算法设计1:按乘法枚举
1)枚举范围为:
A:3——9(A=1,2时积不会得到六位数),B:0——9,