欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

常见算法思想2:递推法

程序员文章站 2022-03-30 20:15:05
...

递推法

递推算法犹如稳重的有经验的老将,使用“稳扎稳打”的策略,不断利用已有的信息推导出新的东西。
在日常应用中有如下两种递推算法:
(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元