枚举算法
枚举算法思想特点是在面对任何问题时它都会去尝试每一种解决方法,在进行归纳推理时,如果逐个考察了某类事件的所有可能情况,因而得出一般结论,那么这个结论可能是可靠的,这种归纳方法叫归纳法
枚举算法基础
枚举算法思想是:将问题所有可能的答案一一列举,然后根据条件判断此答案是否合适,保留合适的,丢弃不合适的
枚举算法基本思路
1.确定枚举对象、枚举范围和判定条件
2.逐一列举可能的解,验证每个解是否是问题的解
枚举算法基本步骤
1.题解的可能范围,不能遗漏任何一个真正解,也要避免有重复
2.判断是否是真正解的方法
3.使可能解的范围将至最小,以便提高解决问题的效率
![](https://s2.ax1x.com/2019/06/23/ZiCRZq.png)
案例
百元买百鸡
公鸡每只5元,母鸡每只3元,小鸡3只1元。用100元买一百只鸡
1 | public static void main(String[] args) { |
运行结果
填写运算符
在下面算式中,添加“+”“-”“×”“÷”4个运算符使等式成立
5 5 5 5 5 = 5
‘×’,’÷’运算符优先级高于’+’,’-‘且’÷’后面的数不可以是0
1 | public static void main(String[] args) { |
运行结果
递推算法
递推算法基础
递推算法可以不断利用已有信息推导出新的东西
顺推法:从已知条件出发,逐步推算出要解决问题的方法
逆推法:从已知结果出发,用迭代表达式逐步推算出问题开始的条件,即顺推法的逆过程
案例
顺推法——裴波那契数列
兔子在出生两个月以后就有繁殖能力,一对兔子每月能生出一对兔子,如果所有兔子都不死,一年后有多少兔子
算法分析
- 第一个月兔子没有繁殖能力,所以还是一对
- 二个月后,一对小兔子生出一对新兔子,所以是两对
- 第三个月后老兔子又生下一对,小兔子还没有繁殖能力,所有有三对
月数: | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | … |
---|---|---|---|---|---|---|---|---|---|
对数: | 1 | 1 | 2 | 3 | 5 | 8 | 13 | 21 | … |
得出特征:前面相邻两项之和等于后一项
由此可知n个月的兔子总数为:Fn=Fn-2+Fn-1
1 | public static void main(String[] args) { |
运行结果
逆推法——银行存款问题
母亲为儿子4年大学生活准备了一笔存款,方式是整存零取,规定儿子每月月底取下一个月生活费,现假设银行年利率为1.71%,计算母亲最少要存入多少钱
算法分析
因为按月取钱,所以需要将4年分为48个月
如果48月后,儿子大学毕业时连本带利要取1000,则要先求出第47个月时银行存款的钱数
47月末=1000/(1+0.0171/12)
46月末=(47月末+1000)/(1+0.171/12)
45月末=(46月末+1000)/(1+0.171/12)
44月末=(45月末+1000)/(1+0.171/12)
43月末=(44月末+1000)/(1+0.171/12)
……
2月末=(3月末+1000)/(1+0.171/12)
1月末=(2月末+1000)/(1+0.171/12)
1 | public static void main(String[] args) { |
运行结果
递归算法
递归算法基础
在计算机编程中,递归算法对解决大多数问题是十分有效的,它能使算法的描述变得简洁而且易于理解
递归算法的特点
1.递归过程一般通过函数或子过程来实现
2.递归算法在函数或子过程的内部,直接或间接的调用自身
3.递归算法实际上是把问题转化为小规模的同类问题,然后再递归调用函数或过程来表示问题的解
使用递归的注意事项
1.递归是在过程或函数中调用自身的过程
2.在使用递归时,必须有一个明确的结束条件(递归出口)
3.递归算法通常显得很简洁,但运行效率很低,所以一般不提倡用递归算法设计程序
4.在递归调用过程中,系统用栈来存储每一层的返回点和局部变量。如果递归次数过多,则会造成栈溢出,所以一般不提倡使用递归算法设计程序
案例
汉诺塔
详解(https://www.cnblogs.com/vsky/p/5014657.html/ )(https://blog.csdn.net/qq_37873310/article/details/80461767 )
1 | public static void move(int n, String x, String y, String z){ |
阶乘
自然数由1~n的n个数连乘积叫做n的阶乘,记作n!
1 | public class JieCheng { |
运行结果
调用过程
分治算法
分治算法也采取了各个击破的方法,将一个规模为N的问题分解成K个规模较小的子问题,这些子问题相互独立且与原问题性质相同,只要求出子问题的解,就可得到原问题的解
分治算法基础
分治算法基本步骤
1.分解,将要解决的问题划分为若干个规模较小的同类问题
2.求解,当子问题划分的足够小时,用较简单的方法求解
3.合并,按原问题要求将子问题的解逐层合并构成原问题的解
案例
大数相乘
问题详解(https://blog.csdn.net/u011446177/article/details/52894191/ )
代码实现
1 | public static void main(String[] args) { |
欧洲冠军杯比赛
欧洲冠军杯初赛阶段采用循环制,设共有n队参加,初赛共进行n-1天,每队都要和其他各队进行一场比赛,然后按照最后积分选拔进入决赛的球队。要求每队每天只能进行一场比赛,并且不能轮空。
算法分析
根据分治算法思路,将所有参赛队伍分为两半,则n队比赛日程表可以通过n/2个队的比赛日程来决定,然后继续划分,直到只剩下最后2队为止。
代码实现
转自(https://www.jianshu.com/p/2089e19e7f99/ )
1 | public class Solution { |