动态规划(一) —— 递归求解

原创 2014年03月10日 12:25:14

一 . 斐波那契数列

题目来源九度OJ:http://ac.jobdu.com/problem.php?pid=1205

题目描述:

N阶楼梯上楼问题:一次可以走两阶或一阶,问有多少种上楼方式。(要求采用非递归)

输入:

输入包括一个整数N,(1<=N<90)。

输出:

可能有多组测试数据,对于每组数据,
输出当楼梯阶数是N时的上楼方式个数。

样例输入:
4
样例输出:
5

定义F[n]为当台阶总数为n时上台阶方式的总数,易得F[1] =  1 ,F[2] = 2。

当n > 2 时,考虑每种方式的最后一步,显然最后一步只有2种方式,上1阶或上2阶,而每种方式对应的种类都是1。

当最后一步采用的是上1阶的方式,则 F[n] 退化成与 F[n - 1] 等价。

同理,若最后一步采用的是上2阶的方式,则 F[n] 退化成与 F[n - 2] 等价。

综上,得出关于 F[n] 的递推公式:F[n] = F[n-1] + F[n-2]   ( F[1] = 1 , F[2] = 2 )

#include <stdio.h>
long long F[91];
int main(){
    F[1] = 1;
    F[2] = 2;
    for(int i = 3 ; i <= 90 ; i ++){
        F[i] = F[i - 1] + F[i - 2];    
    }
    int n;
    while(scanf("%d",&n) != EOF){
        printf("%lld\n",F[n]);    
    }
    return 0;    
}



二 .  错排公式

题目来源九度OJ:http://ac.jobdu.com/problem.php?pid=1451

题目描述:

大家常常感慨,要做好一件事情真的不容易,确实,失败比成功容易多了!
做好“一件”事情尚且不易,若想永远成功而总从不失败,那更是难上加难了,就像花钱总是比挣钱容易的道理一样。
话虽这样说,我还是要告诉大家,要想失败到一定程度也是不容易的。比如,我高中的时候,就有一个神奇的女生,在英语考试的时候,竟然把40个单项选择题全部做错了!大家都学过概率论,应该知道出现这种情况的概率,所以至今我都觉得这是一件神奇的事情。如果套用一句经典的评语,我们可以这样总结:一个人做错一道选择题并不难,难的是全部做错,一个不对。

不幸的是,这种小概率事件又发生了,而且就在我们身边:
事情是这样的——HDU有个网名叫做8006的男性同学,结交网友无数,最近该同学玩起了浪漫,同时给n个网友每人写了一封信,这都没什么,要命的是,他竟然把所有的信都装错了信封!注意了,是全部装错哟!

现在的问题是:请大家帮可怜的8006同学计算一下,一共有多少种可能的错误方式呢?

输入:

输入数据包含多个多个测试实例,每个测试实例占用一行,每行包含一个正整数n(1<n<=20),n表示8006的网友的人数。

输出:

对于每行输入请输出可能的错误方式的数量,每个实例的输出占用一行。

样例输入:
2
3
样例输出:
1
2

同样用 F[n] 表示 n 个信封错装的方式总数,容易得到 F[1] = 0 , F[2] = 1。

当 n > 2 时,讨论 F[n] 的递推公式。

首先可以确定,n号信封所装的信是原本属于编号1 到 n - 1 其中一个信封的,现在假设这个信的编号是m。即m号信装在n号信封中。

再者可以确定,属于n号信封的信也必定被装在编号1到n - 1其中一个信封中,现在假设这个信封的编号是k。即n号信装在k号信封中。

1. 若m == k,则交换这两个信封可以得到2封装对的信,而其他n - 2个信封均装错,此时F[n] 与 F[n - 2] 等价。

2. 若m != k,则交换这两个信封时,只有n号信封能得到正确的信,而其他n - 1个信封的信均装错,此时F[n] 与 F[n - 1] 等价。

由于上面的m取值范围从1到n - 1,故有n - 1种可能取值,即上面的每种等价情况均有n - 1种。

综上,得到F[n]的递推公式:F[n] = (n-1) * F[n-1] + (n-1) * F[n-2]     ( F[1] = 0 , F[2] = 1) 

#include <stdio.h>
long long F[21];
int main(){
    F[1] = 0;
    F[2] = 1;
    for(int i = 3 ; i <= 20; i ++){
        F[i] = (i - 1) * F[i - 1] + (i - 1) * F[i - 2];    
    }
    int n;
    while(scanf("%d",&n) != EOF){
        printf("%lld\n",F[n]);    
    }
    return 0;    
}





重新认识动态规划以及递归

A good solution is to keep track of values that have already been computed by storing them in a dict...
  • bravekingzhang
  • bravekingzhang
  • 2014-02-14 17:36:22
  • 2458

【动态规划】矩阵连乘问题 备忘录方法:自顶向下递归

  • 2013年03月06日 08:31
  • 1KB
  • 下载

字符串相似度算法 递归与动态规划求解分析

1.概念   编辑距离,指的是两个字符串之间,由一个转换成另一个所需的最少编辑操作次数。许可的编辑操作包括:(1)将一个字符替换成另一个字符,(2)插入一个字符,(3)删除一个字符。   ...
  • Aiphis
  • Aiphis
  • 2015-09-17 15:37:02
  • 273

矩阵连乘的JAVA实现(动态规划,递归)

递归,动态规划两种方法实现 1.递归实现: public class MatrixChainDiGui { static int p[] = { 30, 35, 15, 5, 10,...
  • u011980994
  • u011980994
  • 2013-10-08 23:56:21
  • 2587

算法 矩阵连乘 递归+动态规划+备忘录

题目给定n个矩阵,其中两个相邻的矩阵是可乘的,试求出最佳计算次序,使得总计算量最少。例如: A1[30X35] A2[35X15] A3[15X5] A4[5X10] A5[10X20] ...
  • plain_maple
  • plain_maple
  • 2016-12-29 19:11:38
  • 1666

矩阵连乘的动态规划算法(包括递归的备忘录方法)

//矩阵连乘的动态规划算法 #include using namespace std; long MaxtrixChain1(int n); long MaxtrixChain1(int i,...
  • wujunqi11
  • wujunqi11
  • 2015-01-08 14:14:06
  • 1386

递归、分治策略、动态规划以及贪心算法之间的关系

最近集中研究计算智能,其中涉及到递归和动态规划,动态规划实现中又用到了递归,忽然发现这两个概念的差别分得不太清楚。索性把递归、分治策略、动态规划、贪婪选择之间的联系与区别都一并搞清楚吧。...
  • tyhj_sf
  • tyhj_sf
  • 2017-01-01 23:01:59
  • 2864

2018年全国多校算法寒假训练营练习比赛(第一场) - H - 方块与收纳盒(递归)

链接:https://www.nowcoder.net/acm/contest/67/H 来源:牛客网 题目描述     现在有一个大小n*1的收纳盒,我们手里有无数个大小为1*1和2*1的小方块...
  • w326159487
  • w326159487
  • 2018-02-06 20:02:44
  • 30

背包问题---递归及动态规划

背包问题,递归,动态规划
  • cjc211322
  • cjc211322
  • 2014-04-20 11:58:54
  • 1201

背包问题的求解

  • 2018年01月02日 11:09
  • 924B
  • 下载
收藏助手
不良信息举报
您举报文章:动态规划(一) —— 递归求解
举报原因:
原因补充:

(最多只允许输入30个字)