常见算法思想2:递推法

递推法

递推算法犹如稳重的有经验的老将,使用“稳扎稳打”的策略,不断利用已有的信息推导出新的东西。
在日常应用中有如下两种递推算法:
(1)顺推法:从已知条件出发,逐步推算出要解决问题的方法。
(2)逆推法:从已知的结果出发,用迭代表达式逐步推算出问题开始的条件,即顺推法的逆过程。

顺推法

例如斐波那契数列就可以通过顺推法不断递推算出新的数据:

兔子问题:有一对兔子,从出生后第3个月起每个月生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子不死,问第二十个月的兔子对数是多少?

算法分析:

分析:我们要想办法找规律
兔子对数:
第一个月:1;第二个月:1;第三个月: 2;第四个月: 3;第五个月: 5;第六个月: 8;...
由此可见兔子的对象数据是:1,1,2,3,5,8...

规则:
A:从第三项开始,每一项是前两项之程
B:而且说明前两项是已知的

假如相邻的两个月的兔子对数是a,b
第一个相邻的数据:a=1,b=1
第二个相邻的数据:a=1,b=2
第三个相邻的数据:a=2,b=3
第四个相邻的数据:a=3,b=5
看到了:下一次的a是以前的b,下一次的b是以前的a+b;

GO语言描述:
// 获取斐波那契数列
func getFibonacciArray(n int) []int {
    fArr := make([]int, n, n) // 数列第一位从下标1开始
    fArr[0] = 1
    fArr[1] = 1
    for i := 2; i < n; i++ {
        fArr[i] = fArr[i-1] + fArr[i-2]
    }
    return fArr
}
逆推法

银行存款问题:用户A为用户B在银行整存了4年的生活费,B每个月的月初取1000元作为这个月的生活费。而银行的年利率是1.7%,求用户A最少需要存多少钱?

算法分析

可采用逆推法分析存钱和取钱的过程,因为按照月为周期取钱,所以4年可以分为48个月,并对每个月进行计算。
如果第48个月后sun大学毕业连本带息要取1000元,则要求第47个月银行的存钱金额为:
第47个月月末存款=1000/(1+0.0172/12);
第46个月月末存款=(第47存款+1000)/(1+0.0172/12);
第45月末存款=(第46存款+1000)/(1+0.0172/12);
…….
第2月月末存款=(第3月月末存款+1000)/(1+0.0172/12);
第1月月末存款=(第2月末存款+1000)/(1+0.0172/12);

GO语言描述
// 逆推法解决银行存款问题
func F() {
    fArr := make([]float64, 48, 48)
    fArr[47] = 1000
    for i := 46; i >= 0; i-- {
        fArr[i] = (fArr[i+1] + 1000) / (1 + 0.017/12)
        fmt.Printf("逆推第%d月存款余额为%.2f元\n",i+1,fArr[i])
    }
}

打印结果:

逆推第47月存款余额为1997.17元
逆推第46月存款余额为2992.93元
逆推第45月存款余额为3987.28元
...
逆推第4月存款余额为43567.08元
逆推第3月存款余额为44504.03元
逆推第2月存款余额为45439.66元
逆推第1月存款余额为46373.96元
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值