动态规划【Java】

动态规划【Java】,第1张

动态规划【Java】

参考文章:
https://cloud.tencent.com/developer/article/1817113

关于动态规划

动态规划算法的核心就是记住已经解决过的子问题的解。
动态规划有几个典型特征:最优子结构、状态转移方程、边界、重叠子问题。

什么样的问题可以考虑使用动态规划解决呢?

  • 如果一个问题,可以把所有可能的答案穷举出来,并且穷举出来后,发现存在重叠子问题,就可以考虑使用动态规划。

动态规划问题的解题思路:

  • 穷举分析
  • 确定边界
  • 找出规律,确定最优子结构
  • 写出状态转移方程

动态规划的求解方式有两种:

  • 自顶向下的备忘录法
  • 自底向上

用这两个方法来解决一个经典的问题:斐波那契数列

方法一: 自顶向下的备忘录法

public static int fib(int n){
        if(n<=0){
            return n;
        }
        int[] nums=new int[n+1];
        for(int i=0;i<=n;i++){
            nums[i]=-1;
        }
        return fib(n, nums);
    }
    public static int fib(int n,int []nums)
    {
        if(nums[n]!=-1) {//如果不是-1,则表明n的值已经被算过不需要重新计算
            return nums[n];
        }
        if(n<=2) {
            nums[n] = 1;
        } 
        else {
            nums[n]=fib( n-1,nums)+fib(n-2,nums);
        }
        return nums[n];
    }

方法二: 自底向上

public static int fib(int n){
        if(n == 1){
            return 1;
        }
        if(n == 2){
            return 2;
        }
        int[] nums = new int[n + 1];//创建一个用来保存fib第n次的结果的数组
        nums[1] = 1;
        nums[2] = 2;
        for(int i = 3; i <= n; i++){
            nums[i] = nums[i - 1] + nums[i - 2];
        }
        return nums[n];
    }

根据DP的解题思路,来写一下斐波那契数列问题的过程:

  1. 穷举分析
  • 当n = 1时,f(1) = 1;
  • 当n = 2时,f(2) = 2;
  • 当n = 3时,f(3) = 3;
  • 当n = 4时,f(4) = 5;
  • 当n = 5时,f(5) = 8;
  • 当n = 6时,f(6) = 13;
  • 当n = 7时,f(7) = 21;
  1. 确定边界:
    根据穷举我们发现,当n大于3已经呈现出规律f(3) = f(2) + f(1) =3,因此f(1) =1,f(2) = 2就是fib的边界。

  2. 找出规律,确定最优子结构
    明显是:f(n) = f(n-1) + f(n-2)

  3. 写出状态转移方程
    根据前面三步就可以得到状态转移方程了:

    if(n == 1)	f(1) = 1;
    if(n == 2)  f(2) = 2;
    else	f(n) = f(n - 1) + f(n - 2);
    

例题:

  • 买卖股票的最佳时机:
  • 爬楼梯
  • 打家劫舍
  • 三道简单题

持续更新。。。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5437736.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-11
下一篇 2022-12-11

发表评论

登录后才能评论

评论列表(0条)

保存