动态规划入门--n的阶乘,斐波那契数列,三角形最大值路径

最近我也在学习动态规划,略有一点感触,赶忙记录下来,加深印象,也希望能在评论区看见更加好的讲法,共同进步。

如有不足之处,还请多多包涵

可以根据目录按需查看

Top

本人也翻过许多讲递归的博客,看到一句夺人眼球的话:
人理解迭代,神理解递归
哇,我也想成神诶



现在感觉自己快成神经了 。。。
坚持学!
本文的每段java代码,你们也可以copy到你们的ide上自行运行,看注释帮助进行理解。

何为动态规划

把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解

n的阶乘

阶乘在数学上的定义
在这里插入图片描述
主要看我代码里面的注释

public class n的阶乘 {
   

    public static int 递归阶乘(int n){
   
        //自顶向下,我们已经知道了该怎么求,该分解n,求n*n-1*n-2*....*1
        if(n==1){
   
            return 1;    //最后一个是 1 先设置好
        }
        return n*递归阶乘(n-1);

//        分析,第一次return是:就是5*阶乘(4)
//             第二次return是:4*阶乘(3)
//             第三次return是:3*阶乘(2)
//             第四次return是:2*阶乘(1)
//        回带:
//             第四次的return  2 作为第三次阶乘(2)的值
//             第三次的return  6 作为第二次阶乘(3)的值
//             .....
//             第一次,最开始的return就是最后的值了 120

    }

    public static int DP阶乘(int n){
   
        //自底向上,那就是需要我们验证,我们通过假设一种阶乘的定义叫n! 开始实验证明
        //2!=1*2=2   //3!=1*2*3=6  每次记录下来步骤和值,发现n的阶乘的值都可以由前面一个阶乘的值*n本身
        // 最后大佬在数学界给出定义,n的阶乘的定义应该是由1*2*....*n
        int []rst = new int[n+1];
//      定义边界值
        if(n<=1){
   
            return 1;
        }
        rst[0] = 1;        //数组下标从0开始,所以让rst[0]=1,好让rst[1]=1,所以创建数组时需要n+1的空间
        for(int i=1;i<rst.length;i++){
   
            rst[i]=rst[i-1]*i;
        }
        return rst[n];
        //每一个过程都是由小至大,
        // 先记录1*1的值(1)  存在rst[1],
        // 再记录1*2的值(2)  存在rst[2],
        // 再记录2*3的值(6)   存在rst[3],
        // 再记录6*4的值(24)  存在rst[4],
        // 再记录24*5的值(120) 存在rst[5]     所以创建数组时用n+1
    }

    public static void main(String[] args) {
   
         //递归阶乘
        System.out.println(n的阶乘.递归阶乘(5));
        System.out.println(n的阶乘.DP阶乘(5));
    }
}

n的阶乘的算法还是很简单的,容易让人理解到缩小问题规模是怎么样的一个过程。两个算法的注释也很清晰的表述了DP和递归最大的区别。

来看下一个例子,将更好的帮助你理解DP记忆结果的优势,避免重复计算

斐波那契数列

先来看斐波那契数列的算法定义
在这里插入图片描述
下面的代码中写了斐波那契数列的递归算法,动态规划的自顶向下和自底向上的三种算法。
重点还是要看注释,跟着注释一行行看代码


public class 斐波那契数列 {
   

//      f(1)=1
//      f(2)=1
//      f(n)=f(n-1)+f(n-2)
//      看下面的算法就应该比较明显了,自顶向下,直接用公式递归
    public static int 递归Fbnq(int n){
   
        if(n<=2){
   
            return 1;
        }
        return 递归Fbnq(n-1)+递归Fbnq(n-2);
//      分析:
//        递归Fbnq(5)return 递归Fbnq(4)+递归Fbnq(3)
//        递归Fbnq(4)return 递归Fbnq(3)+递归Fbnq(2)
//        递归Fbnq(3)return 递归Fbnq(2)+递归Fbnq(1)
//      开始回带:
//        递归Fbnq(3)=2
//        递归Fbnq(4)=3
//        递归Fbnq(5)=5
//      所以返回值为 5
    }

    public static int Fibonacci(int n){
   
//    
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值