`

Java 递推思想

阅读更多
像俺一样奋斗在一线的码农们,一谈到学编程,都是说要学会XX语言就OK了,其实我们理解的有一点点的偏差,因为我们只说到了
三分之一,其实真正的编程应该是:编程=数据结构+算法+XX语言。
    对的,XX语言只是一个工具而已,就好比我们知道用笔来写字,但是不见得我们就能写出一手让张恨水为之倾倒的好字,其实我也说过
算法不仅仅用于程序设计中,在我们的生活中也处处存在着算法,比如记得我大二学C#的时候,无聊的我们就出了个猜美女芳龄的问题。

@Test  
public void testMeiMei() {  
    Random random = new Random();  
  
    Scanner scanner = new Scanner(System.in);  
    int mm = random.nextInt(17) + 16;  
  
    int guess = 0;  
  
    int count = 0;  
  
    System.out.println(mm + "现有一美女,请猜她的芳龄(16,32)\n");  
  
    do {  
        System.out.println("请输入你认为正确的年龄:\t");  
  
        try {  
            guess = scanner.nextInt();  
        } catch (Exception e) {  
            return;  
        }  
        if (guess < mm)  
            System.out.println("低了!\n");  
  
        if (guess > mm)  
            System.out.println("高了!\n");  
  
        if (guess == mm)  
            System.out.println("恭喜,猜对了!\n");  
  
        count = count + 1;  
  
    } while (mm != guess);  
  
    System.out.println("你一共猜了:\t" + count + "次");  
  
}  

针对这个问题,大家如何 “又快又稳” 的猜出mm的芳龄呢?如果是一个不懂算法的人,估计就是一个for循环进行查找,但是这个的复杂度是O(n)。
那么懂算法的人就会利用年龄有序这个特点进行"二分查找“,这个复杂度就是log2N,所以说学算法,懂算法可以给我们实际应用中带来更好的解决方案。

好了,不扯了,今天主要讲的是“递推思想”。
一: 概念
     通过已知条件,利用特定关系逐步递推,最终得到结果为止,核心就是不断的利用现有信息推导出新的东西。

二:分类
     当然递推中有两种,“顺推”和“逆推“
     顺推:从条件推出结果。
     逆推:从结果推出条件。
呵呵,是不是觉的有一种policeman破案的感觉。

三: 举例
<1> 顺推的例子
      上过大学的应该都知道著名的“斐波那契”数列吧,说的是繁殖兔子的问题,题目我就大概说一下。
如果1对兔子每月能生1对小兔子,而每对小兔在它出生后的第3个月就可以生1对小兔子,如果从1对初生的小兔子开始,1年后能
繁殖多少兔子?
思路:其实这个问题我们可以将兔子划分为“1月大的兔子“,”2月大的兔子“,”3月大的兔子“。
        ① 初始时:            一对1月大小兔子,总数为1对。
        ② 第一个月:         1月大的小兔子变成2月大的兔子,总数还是1对。
        ③ 第二个月:         2月大的小兔子变成3月大的兔子,繁殖了一对小兔子,总数为2对。
        ④ 第三个月:         3月大的兔子tmd有生了一对小兔子,上个月1月大的小兔子变成了2月大的兔子,总数为3对。
         ......                    ......
        F0=1
        F1=1
        F2=F0+F1
        F3=F1+F2
        ......
        Fn=Fn-2+Fn-1

大家看看,是不是体现了”递推“的核心思想,代码也很简单。
@Test  
public void feibonaqie() {  
    int month = 12;  
    int[] f = new int[month];  
    f[0] = 1;  
    f[1] = 1;  
  
    for (int i = 2; i < month; i++) {  
        f[i] = f[i - 2] + f[i - 1];  
    }  
  
    for (int i = 0; i < month; i++) {  
        System.out.println("第 " + i + " 个月,兔子总数:" + f[i]);  
    }  
}  

测试结果:
第 0 个月,兔子总数:1 
第 1 个月,兔子总数:1 
第 2 个月,兔子总数:2 
第 3 个月,兔子总数:3 
第 4 个月,兔子总数:5 
第 5 个月,兔子总数:8 
第 6 个月,兔子总数:13 
第 7 个月,兔子总数:21 
第 8 个月,兔子总数:34 
第 9 个月,兔子总数:55 
第 10 个月,兔子总数:89 
第 11 个月,兔子总数:144

<2> 逆推的例子
       这个一个关于存钱的问题,一个富二代给他儿子的四年大学生活存一笔钱,富三代每月只能取3k作为下个月的生活费,采用的是整存零取的方式,
   年利率在1.71%,请问富二代需要一次性存入多少钱。

思路: 这个题目是我们知道了结果,需要逆推条件, 第48月富三代要连本带息的把3k一把取走,那么
        第47月存款应为: (第48个月的存款+3000)/(1+0.0171/12(月));
        第46月存款应为: (第47个月的存款+3000)/(1+0.0171/12(月));
         .....                    .....
        第1个月存款应为: (第2个月的存款+3000)/(1+0.0171/12(月));
@Test  
public void deposit() {  
    int month = 49;  
    double[] f = new double[month];  
    f[48] = 3000d;  
    double monthRate = 1.71 / 100 / 12;  
  
    for (int i = 47; i > 0; i--) {  
        f[i] = (f[i + 1] + 3000) / (1 + monthRate);  
    }  
    for (int i = 48; i > 0; i--) {  
        System.out.println("第 " + i + " 个月,本息总额:" + f[i]);  
    }  
}  


第 48 个月,本息总额:3000.0 
第 47 个月,本息总额:5991.462166412862 
第 46 个月,本息总额:8978.667565132548 
第 45 个月,本息总额:11961.622253421421 
第 44 个月,本息总额:14940.332279922532 
第 43 个月,本息总额:17914.803684671875 
第 42 个月,本息总额:20885.04249911064 
第 41 个月,本息总额:23851.054746097452 
第 40 个月,本息总额:26812.846439920566 
第 39 个月,本息总额:29770.423586310073 
第 38 个月,本息总额:32723.792182450085 
第 37 个月,本息总额:35672.95821699087 
第 36 个月,本息总额:38617.92767006103 
第 35 个月,本息总额:41558.706513279605 
第 34 个月,本息总额:44495.300709768184 
第 33 个月,本息总额:47427.716214163 
第 32 个月,本息总额:50355.958972627006 
第 31 个月,本息总额:53280.03492286193 
第 30 个月,本息总额:56199.94999412031 
第 29 个月,本息总额:59115.71010721753 
第 28 个月,本息总额:62027.3211745438 
第 27 个月,本息总额:64934.789100076196 
第 26 个月,本息总额:67838.11977939056 
第 25 个月,本息总额:70737.31909967352 
第 24 个月,本息总额:73632.3929397344 
第 23 个月,本息总额:76523.34717001712 
第 22 个月,本息总额:79410.18765261215 
第 21 个月,本息总额:82292.92024126834 
第 20 个月,本息总额:85171.55078140483 
第 19 个月,本息总额:88046.0851101229 
第 18 个月,本息总额:90916.5290562178 
第 17 个月,本息总额:93782.88844019052 
第 16 个月,本息总额:96645.1690742597 
第 15 个月,本息总额:99503.37676237331 
第 14 个月,本息总额:102357.5173002205 
第 13 个月,本息总额:105207.59647524328 
第 12 个月,本息总额:108053.6200666483 
第 11 个月,本息总额:110895.59384541858 
第 10 个月,本息总额:113733.52357432517 
第 9 个月,本息总额:116567.41500793885 
第 8 个月,本息总额:119397.27389264184 
第 7 个月,本息总额:122223.10596663937 
第 6 个月,本息总额:125044.91695997141 
第 5 个月,本息总额:127862.71259452422 
第 4 个月,本息总额:130676.49858404195 
第 3 个月,本息总额:133486.2806341383 
第 2 个月,本息总额:136292.064442308 
第 1 个月,本息总额:139093.85569793844 

参考:http://blog.csdn.net/m13666368773/article/details/7531453
分享到:
评论

相关推荐

    学习常用算法之(4)递推法

    在计算机科学中,递推法是一种重要的算法思想,它可以帮助我们解决复杂的问题。 递推法的特征: 1. 有穷性:一个算法必须保证执行有限步之后结束。 2. 确切性:算法的每一步骤必须确切定义。 3. 输入:一个算法有 ...

    贪心算法+递推+各种查找、排序算法

    其核心思想是从源节点开始,逐步扩展到图中的其他节点,每次选择距离最近的未访问节点加入到已知最短路径的集合中。这种方法保证了每一步都是局部最优的,最终能够得到全局最优的最短路径。 ### 递推算法 递推算法...

    蓝桥杯Java试题汇总.pdf

    * 解题思路:首先分析问题的规律,发现可以使用递推思想来实现。具体代码实现可以使用 Java 语言,使用递推算法来生成字符串 AN。 4. 芯片测试 问题描述有 n2≤n≤20 块芯片,有好有坏,已知好芯片比坏芯片多;每个...

    java统计数字问题

    Java 统计数字问题 在本题中,我们需要统计数字问题,即统计从 0 到 9 各个数字在所有 n 位数...本题中我们学习了 Java 基础知识、统计数字问题的算法设计思想、Java 程序设计思想、递推式的应用和程序优化等知识点。

    Java实现 LeetCode 790 多米诺和托米诺平铺(递推)

    这两种方法都利用了递推的思想,通过计算和存储前几行的解来求解当前行的解,从而有效地解决了这个问题。在实际编程中,动态规划经常用于解决具有重叠子问题和最优子结构的问题,如游戏策略、图论问题、组合优化等。

    java大神进阶之路.pdf

    - 算法思想:包括递推、递归、穷举、贪心、分治、动态规划、迭代、分枝界限等核心思想。 - 经典算法:掌握经典的排序算法(插入排序、冒泡排序、快速排序等)和查找算法(顺序查找、二分查找等)。 - 高级数据结构:...

    Java常用算法手册源代码

    3.3.1 递推算法基本思想 3.3.2 递推算法实例 3.4 递归算法思想 …… 第2篇 算法应用篇 第4章 排序算法 第5章 查找算法 第6章 基本数学问题 第7章 数据结构问题 第8章 数论问题 第9章 算法经典趣题 **0章 游戏中的...

    JAVA实现棋盘覆盖问题

    ### JAVA 实现棋盘覆盖问题 #### 知识点概览 ...通过上述分析可以看出,该程序成功实现了棋盘覆盖问题的解决方案,并利用了分治法的思想,借助Java语言的基础语法完成了一个实用而有趣的递归算法实现。

    数据结构与算法(JAVA语言版解密)

    递归章节探讨了递归的概念、递归的实现与堆栈的关系,基于归纳的递归方法,以及递推关系的求解,并介绍了分治法的基本思想及其应用示例。 树和图是更为复杂的数据结构,书中分别介绍了它们的定义、基本术语、存储...

    java写的0、1背包问题的解决方案

    0、1背包问题的Java解决方案不仅体现了动态规划思想,还展示了如何在实际编程中应用这种思想。它对于理解和掌握动态规划算法具有重要意义,也是许多面试和算法竞赛中常见的题目。通过不断实践和优化,我们可以提高...

    JAVA语言版数据结构与算法

    - **分治法的基本思想**:讲解分治法的基本思想及其适用场景。 - **矩阵乘法**:介绍如何使用分治法实现矩阵乘法。 - **选择问题**:讨论使用分治法解决选择问题的方法。 #### 第六章:树 - **树的定义及基本...

    java开发经典算法

    3. **递推法**:递推是根据前一状态(或前几状态)推导出当前状态的方法。它通常与数学公式相结合,用于解决具有明显规律性的问题,如斐波那契数列或汉诺塔问题。 4. **递归**:递归是一种函数或方法调用自身的技术...

    数据结构算法JAVA

    - **分治法的基本思想**:解释了分治法的核心思想。 - **矩阵乘法**:示例说明了如何使用分治法优化矩阵乘法。 - **选择问题**:介绍了如何使用分治法解决特定的选择问题。 #### 第六章:树 - **树的定义及基本...

    蓝桥杯练习题目汇总

    ### 蓝桥杯练习题目汇总 #### 一、入门训练 ##### 1.... **知识点:** - **定义与递推公式:** Fibonacci数列是一种经典的数列,其递推公式为:\...通过这些练习可以帮助初学者掌握基本的数据结构、算法思想和编程技巧。

    数据结构与算法(JAVA语言版)

    - **分治法的基本思想**:解释分治法的基本原理和步骤。 - **矩阵乘法**:演示如何使用分治法优化矩阵乘法的过程。 - **选择问题**:介绍分治法在解决选择问题中的应用。 #### 树 - **树的定义及基本术语** - ...

    数据结构(Java)

    ### 数据结构(Java) #### 知识点概览 本文档提供了一套全面的数据结构教程,专注于使用Java语言进行讲解。内容涵盖了从Java基础到高级数据结构与算法的基础理论及其实现方法。以下是对各章节内容的详细解析。 #...

Global site tag (gtag.js) - Google Analytics