算法设计 之 递推法

递推法就是根据已知条件,分析推导出问题中的联系,然后一步一步进行推倒直至得到结果。

根据具体问题我们需要选择是正推还是逆推来解决问题。

下面先举一个递推中的经典例子,就是求兔子数量的问题:

现有一只一个月大的兔子,已知当兔子在第三个月大时每月就可以生下一只小兔子(好吧,就按兔子是无性繁殖的),求一年后兔子的总数量。

我们根据问题分析,发现可以把兔子分三类:一个月大、二个月大、三个或三个以上月大,列表分析:





































月份 1月大 2月大 >=3月大
1 1 0 0
2 0 1 0
3 1 0 1
4 1 1 1
5 2 1 2
……      

根据上面图表分析可知:

下月“一月大”的兔子数量等于上月“>=3月大”的兔子数量;

下月“二月大”的兔子数量等于上月“一月大”的兔子数量;

下月“>=3月大”的兔子数量等于上月“二月大”+上月“>=3月大”的兔子数量;

既然分析完问题,代码就很简单了:


/// <summary>
/// 递推(正推)计算兔子的数量
/// </summary>
public static void ShowRabbitsCount()
{
int oneMonthCount = 1;
int twoMonthCount = 0;
int threeOrMoreMonthCount = 0;

for (int month = 2; month <= 12; month++)
{
//临时存储上月各种兔子数量
int preOneMonthCount = oneMonthCount;
int preTwoMonthCount = twoMonthCount;
int preThreeOrMoreMonthCount = threeOrMoreMonthCount;

//更新本月各种兔子的数量
oneMonthCount = preTwoMonthCount+preThreeOrMoreMonthCount;
twoMonthCount = preOneMonthCount;
threeOrMoreMonthCount += preTwoMonthCount;

Console.WriteLine(string.Format("第 {0} 个月兔子的总数为:{1}", month, oneMonthCount + twoMonthCount + threeOrMoreMonthCount));
}
}

运行结果:

下面再看一个逆推的例子:

假设有一个人从1月份开始到本年12月初时体重减少到150斤,他每个月增加的体重为当月初体重的2%,每月锻炼减少的体重为10斤(这里也按这10斤是月底突然减掉的),计算此人一月初时的体重。

根据问题分析:

12月初的体重为150斤,然后: 本月初体重+10=上月初体重*1.02


/// <summary>
/// 递推(逆推)计算开始时的体重
/// </summary>
public static void ShowWeight()
{
double endWeight = 150;
double perMonthReduce = 10;
for (int month = 11; month > 0; month--)
{
double preStartWeight = (endWeight + perMonthReduce) / 1.02;
endWeight = preStartWeight;

Console.WriteLine(string.Format("第 {0} 个月的开始体重为:{1}", month, preStartWeight));
}
}

运行结果:

时间: 2024-11-08 18:51:12

算法设计 之 递推法的相关文章

算法基础二 递推法

/*递推法*/ /*斐波那契数列 1 1 2 3 5 8 13..... f(n)?*/ /*递推法的特点是由前向后推算,因此注意起始条件,并在推算过程中保存结果供下一步推算使用~*/ #include<iostream> using namespace std; int f1(int n) { if (n < 3)return 1; else { int t1 = 1; int t2 = 1; for (int i = 2; i < n; i++) { int temp = t1

001-算法-递推法

一.概念: 递推算法是一种简单的算法,即通过已知条件,利用特定关系得出中间推论,直至得到结果的算法.递推分为顺推和逆推两种. 递推算法使用“步步为营”的方法,不断利用已有的信息推导出新的东西. 顺推法:是指从已知条件出发,逐步推算出要解决问题的方法.例如:斐波拉契数列就可以通过顺推法不断递推算出新的数据. 逆推法:是从已知的结果出发,用迭代表达式逐步推算出问题开始的条件,即顺推法的逆过程. demo : http://blog.csdn.net/jtlyuan/article/details/7

递推(一):递推法的基本思想

所谓递推,是指从已知的初始条件出发,依据某种递推关系,逐次推出所要求的各中间结果及最后结果.其中初始条件或是问题本身已经给定,或是通过对问题的分析与化简后确定. 利用递推算法求问题规模为n的解的基本思想是:当n=1时,解或为已知,或能非常方便地求得:通过采用递推法构造算法的递推性质,能从已求得的规模为1.2.….i−1的一系列解,构造出问题规模为i的解.这样,程序可从i=0或i=1出发,重复地由已知至i−1规模的解,通过递推,获得规模为i的解,直至获得规模为n的解. 可用递推算法求解的问题一般有

递推(二):递推法的应用

下面通过一些典型实例及其扩展来讨论递推法的应用. [例2]骨牌铺方格 在2×n的一个长方形方格中,用一种2×1的骨牌铺满方格.输入n(n<=40),输出铺放方案的总数. 例如n=3时,为2×3方格,骨牌的铺放方案有三种,如下图1所示. 图1  2×3方格的骨牌铺放方案 (1)编程思路. 设f[i]为铺满2*n方格的方案数,则有    f[i]=f[i-1]+f[i-2]. 其中,f[i-1]为铺满2*(n-1)方格的方案数(既然前面的2*(n-1)的方格已经铺满,那么最后一个只能是竖着放).f[

实用算法的分析与程序设计——递推法(顺推法)包含实例,代码

顺推法即由边界条件出发,通过递推关系式推出后项值,再由后项值按递推关系式推出再后项值...依次递推,直至从问题初始陈述向前推进到这个问题的解为止. 实例 代码 #include<iostream> #include<stdlib.h> using namespace std; const int maxN = 60 ; int N = 4 ,d = 2 , m = 3; float a1 = 2 ,an = 5; void input() { cout<<"i

实用算法的分析与程序设计——递推法(贮油点 含算法分析、代码)

倒推法 所谓倒推法就是在不知初始值的情况下,经某种递推关系而获知问题的解或目标,再倒过来,推知它的初始条件,因为这类问题的运算过程是一一映射的,故可分析得其递推公式.然后再从这个解或目标出发,采用倒推手段,一步步地倒推到这个问题的初始陈述. 贮油点 一辆重型卡车欲穿越1000公里的沙漠,卡车耗油为1升/公里,卡车总载油能力为500公升,显然卡车装一次油是过不了沙漠的.因此四级必须设法在沿途建立几个储油点,使卡车能顺利穿越沙漠,试问司机如何建立这些贮油点?每一贮油点应存多少汽油,才能使卡车以消耗最

实用算法的分析与程序设计——递推法(倒推法)

倒推法就是在不知初始值的情况下,经某种递推关系而获知问题的解或目标,再倒过来,推知它的初始条件.因为这类问题的运算过程是一一映射的,故可分析得其递推公式,然后再从这个解或目标出发,采用倒推手段,一步步地倒推到这个问题的初始陈述. 贮油点 一辆重型卡车欲穿过1000公里的沙漠,卡车耗油为1升/公里,卡车总载油能力为500公升,显然卡车装一次油是过不了沙漠的,因此四级必须设法在沿途建立几个贮油点,使卡车能顺利穿越沙漠,试问司机如何建立这些贮油点?每一贮油点应存多少汽油,才能使卡车以消耗最少汽油的代价

约瑟夫环-公式递推法

约瑟夫问题 约瑟夫问题是个著名的问题:N个人围成一圈,第一个人从1开始报数,报M的将被杀掉,下一个人接着从1开始报.如此反复,最后剩下一个,求最后的胜利者. 例如只有三个人,把他们叫做A.B.C,他们围成一圈,从A开始报数,假设报2的人被杀掉. 首先A开始报数,他报1.侥幸逃过一劫. 然后轮到B报数,他报2.非常惨,他被杀了 C接着从1开始报数 接着轮到A报数,他报2.也被杀死了. 最终胜利者是C 解决方案 普通解法 刚学数据结构的时候,我们可能用链表的方法去模拟这个过程,N个人看作是N个链表节

算法设计与分析——回溯法算法模板

以深度优先方式系统搜索问题解的算法称为回溯法.在回溯法中,解空间树主要分为了四种子集树.排列树.n叉树和不确定树. 在<算法设计与分析课本>中介绍了11个回溯法的问题样例,这里根据解空间树的类型做一个分类. 子集树 装载问题 符号三角形问题 0-1背包问题 最大团问题 算法模板: void backtrack(int t) { if(搜索到叶子结点) { return; } for(i=0; i<=1; i++) //01二叉树 { if(满足约束函数和限界函数)//剪枝 { backt